19/01/22 17:36
dylan666
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
aaa
20/01/22 13:52
Neo1986
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).
Public Class ThreadSincronizzatore
#Region "VARIABILI INTERNE"
'gestione loop del thread
Private LoopThread As Boolean = False
'thread di sistema
Private ThreadInterno As System.Threading.Thread = Nothing
#End Region
#Region "VARIABILI ESPOSTE DAL THREAD"
'espongo stato del thread
Public ThreadInEsecuzione As Boolean = False
'espongo eventuali errori
Public Errore As String = ""
'EVENTUALE PERCORSO DELLA CARTELLA DA MANIPOLARE
Public PercorsoCartella as string = "C:\PROVA"
#End Region
#Region "GESTIONE START/STOP DEL THREAD"
Public Sub StartThread()
Try
'setto a true il loop infinito del thread
LoopContinuo = True
'creo il thread
ThreadInterno = New System.Threading.Thread(AddressOf CorpoThread)
'avvio il thread
ThreadInterno.Start()
Catch ex As Exception
Errore = "ERR.0000 : Errore durante l'avvio del thread : " + ex.ToString
End Try
End Sub
Public Sub StopThread()
Try
'setto a false il loop continuo del thread
LoopContinuo = False
'memorizzo istante richiesta stop del thread
Dim Istante As Date = Now
'attendo che il thread sia stato effettivamente terminato
Do
'controllo timeout attesa stop thread
If Now.Subtract(Istante).TotalSeconds >= 5 Then
Errore = "Timeout stop thread"
Exit Do
End If
'pausa per permettere agli altri thread di lavorare
Threading.Thread.Sleep(1)
Loop While ThreadInEsecuzione = True
'una volta terminato il thread libero le risorse
ThreadInterno.Abort()
Catch ex As Exception
End Try
End Sub
#End Region
#Region "CORPO DEL THREAD"
Private Sub CorpoThread()
Do
'segnalo thread in esecuzione
ThreadInEsecuzione = True
'INSERISCI QUI TUTTO QUELLO CHE VUOI FARE
'pausa per permettere agli altri thread di lavorare
Threading.Thread.Sleep(10)
Loop While LoopThread = True
'segnalo thread terminato
ThreadInEsecuzione = False
End Sub
#End Region
End Class
E lo avvii dall'esterno così :
Public Processo1 as ThreadSincronizzatore = new ThreadSincronizzatore
Processo1.PercorsoCartella = "C:\NUOVOPERCORSO"
Processo1.StartThread()
Quando lo vuoi arrestare
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 20/01/22 13:58
aaa
21/01/22 6:14
Carlo
in programmazione tutto è permesso
21/01/22 13:30
dylan666
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
aaa
21/01/22 17:05
Carlo
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.
in programmazione tutto è permesso
24/01/22 8:13
Neo1986
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.
aaa