Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [VB. NET] - Esecuzioni istruzioni in parallelo con un servizio Windows
Forum - C# / VB.NET - [VB. NET] - Esecuzioni istruzioni in parallelo con un servizio Windows

Avatar
dylan666 (Normal User)
Pro


Messaggi: 129
Iscritto: 08/09/2009

Segnala al moderatore
Postato alle 18:36
Mercoledì, 19/01/2022
Ciao a tutti, da autodidatta ho creato un piccolo servizio Windows che monitoria una certa cartella e fa delle operazioni: estrai dei file, li rinomina, li sposta, li cancella ecc. e gli faccio scrivere i passaggi che esegue in un file di testo (ma so che potrei usare anche un registro eventi).
La cartella da monitorare e altre variabili le ho salvate nella chiave "Parameters" del servizio del registro di Windows.

Ora vorrei fare la stessa cosa su più cartelle e qui arrivano le due domande:
Come gestisco la chiamata delle sub e function in mio possesso in modo che vengano eseguite in "parallelo" sulle cartelle?
Ho letto di BackgroundWorker, ThreadPool, Tasks, Thread(AddressOf Me.DoSomething) ma mi sono un po' perso e vorrei capire cosa studiare in particolare.

Altra domanda: come gestisco una lista dinamica di N voci di cartelle da monitorare? Posso usare sotto-chiavi di Parameters o è meglio un file di testo o XML?

Grazie anticipatamente delle risposte

PM Quote
Avatar
Neo1986 (Ex-Member)
Pro


Messaggi: 97
Iscritto: 21/06/2010

Segnala al moderatore
Postato alle 14:52
Giovedì, 20/01/2022
Ciao dylan,

Premetto che non sono un esperto di servizi di Windows.

Io quando ho necessità di eseguire lo stesso compito su più "soggetti" diversi utilizzo i thread, in questo modo quando avvii il processo avvii un numero di thread pari al numero di cartelle da monitorare/manipolare (così se trovi qualche bug cambi solo il codice in una classe).

Codice sorgente - presumibilmente VB.NET

  1. Public Class ThreadSincronizzatore
  2.  
  3. #Region "VARIABILI INTERNE"
  4.  
  5.     'gestione loop del thread
  6.     Private LoopThread As Boolean = False
  7.  
  8.     'thread di sistema
  9.     Private ThreadInterno As System.Threading.Thread = Nothing
  10.  
  11. #End Region
  12.  
  13. #Region "VARIABILI ESPOSTE DAL THREAD"
  14.  
  15.     'espongo stato del thread
  16.     Public ThreadInEsecuzione As Boolean = False
  17.  
  18.     'espongo eventuali errori
  19.     Public Errore As String = ""
  20.  
  21.     'EVENTUALE PERCORSO DELLA CARTELLA DA MANIPOLARE
  22.     Public PercorsoCartella as string = "C:\PROVA"
  23.  
  24. #End Region
  25.  
  26. #Region "GESTIONE START/STOP DEL THREAD"
  27.  
  28.     Public Sub StartThread()
  29.  
  30.         Try
  31.  
  32.             'setto a true il loop infinito del thread
  33.             LoopContinuo = True
  34.  
  35.             'creo il thread
  36.             ThreadInterno = New System.Threading.Thread(AddressOf CorpoThread)
  37.  
  38.             'avvio il thread
  39.             ThreadInterno.Start()
  40.  
  41.         Catch ex As Exception
  42.             Errore = "ERR.0000 : Errore durante l'avvio del thread : " + ex.ToString
  43.         End Try
  44.  
  45.     End Sub
  46.  
  47.     Public Sub StopThread()
  48.  
  49.         Try
  50.  
  51.             'setto a false il loop continuo del thread
  52.             LoopContinuo = False
  53.  
  54.             'memorizzo istante richiesta stop del thread
  55.             Dim Istante As Date = Now
  56.  
  57.             'attendo che il thread sia stato effettivamente terminato
  58.             Do
  59.  
  60.                 'controllo timeout attesa stop thread
  61.                 If Now.Subtract(Istante).TotalSeconds >= 5 Then
  62.                     Errore = "Timeout stop thread"
  63.                     Exit Do
  64.                 End If
  65.  
  66.                 'pausa per permettere agli altri thread di lavorare
  67.                 Threading.Thread.Sleep(1)
  68.  
  69.             Loop While ThreadInEsecuzione = True
  70.  
  71.             'una volta terminato il thread libero le risorse
  72.             ThreadInterno.Abort()
  73.  
  74.         Catch ex As Exception
  75.  
  76.         End Try
  77.  
  78.     End Sub
  79.  
  80. #End Region
  81.  
  82. #Region "CORPO DEL THREAD"
  83.  
  84.     Private Sub CorpoThread()
  85.  
  86.         Do
  87.  
  88.             'segnalo thread in esecuzione
  89.             ThreadInEsecuzione = True
  90.  
  91.             'INSERISCI QUI TUTTO QUELLO CHE VUOI FARE
  92.  
  93.             'pausa per permettere agli altri thread di lavorare
  94.             Threading.Thread.Sleep(10)
  95.  
  96.         Loop While LoopThread = True
  97.  
  98.         'segnalo thread terminato
  99.         ThreadInEsecuzione = False
  100.  
  101.     End Sub
  102.  
  103. #End Region
  104.  
  105. End Class



E lo avvii dall'esterno così :

Codice sorgente - presumibilmente C# / VB.NET

  1. Public Processo1 as ThreadSincronizzatore = new ThreadSincronizzatore
  2. Processo1.PercorsoCartella = "C:\NUOVOPERCORSO"
  3. Processo1.StartThread()



Quando lo vuoi arrestare

Codice sorgente - presumibilmente Plain Text

  1. Processo1.StopThread()



Per quanto riguarda quella lista dinamica mi sembra di aver capito che è una lista delle cartelle da controllare, perchè invece di complicarti la vita con un xml (soluzione sicuramente più elegante della mia), non utilizzi un semplice txt/csv con StreamWriter per scrivere il file e streamreader per leggerlo ?

Comunque attendi anche qualche consiglio da altri del forum, magari ti suggeriscono qualche sistema più ottimale/pratico.


Ultima modifica effettuata da Neo1986 il 20/01/2022 alle 14:58
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1231
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 7:14
Venerdì, 21/01/2022
Usa FileSystemWatcher:
https://docs.microsoft.com/it-it/dotnet/api/system.io.files ...

per generare eventi quando vengono modificati files o cartelle.

Le sub richiamate le puoi far lavorare in parallelo con BackGroundWorker:
https://docs.microsoft.com/en-us/dotnet/api/system.componen ...


in programmazione tutto è permesso
PM Quote
Avatar
dylan666 (Normal User)
Pro


Messaggi: 129
Iscritto: 08/09/2009

Segnala al moderatore
Postato alle 14:30
Venerdì, 21/01/2022
Grazie a entrambi per le risposte.
Vedo che sono stati consigliati sia System.Threading.Thread che BackGroundWorker
Ora, senza entrare in approfondimenti verticali che magari sono troppo per il mio scopo, ce ne è uno che per motivi pratici è "meglio" dell'altro?
Che sostanziali differenze hanno? Io ho provato a documentarmi ma non ho trovato una risposta chiara e sintetica

Grazie

PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 1231
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 18:05
Venerdì, 21/01/2022
BackGroundWorker secondo me, per il compito che ti prefiggi è più indicato, perché ha gli eventi automatizzati (ProgressChanged e RunWorkerCompleted) e non ti devi preoccupare di scrivere codice per gestire il lavoro asincrono mentre è in esecuzione.

Ti posto un progetto d'esempio che ho scritto anni fa quando l'ho studiato.


Carlo ha allegato un file: BackGroundWorekerReport.zip (25662 bytes)
Clicca qui per scaricare il file


in programmazione tutto è permesso
PM Quote
Avatar
Neo1986 (Ex-Member)
Pro


Messaggi: 97
Iscritto: 21/06/2010

Segnala al moderatore
Postato alle 9:13
Lunedì, 24/01/2022
Effettivamente visto che non hai esperienza con Thread e Backgroundworker credo abbia ragione Carlo.

Fai esperienza con i background (che hanno la maggior parte delle funzioni/eventi già gestiti) e quando ti sentirai più sicuro potrai cimentarti con i thread.

PM Quote