2009-03-05 10 views
9

Recentemente ho provato a usare backgroundworker invece di thread "classici" e mi sto rendendo conto che sta causando, almeno per me, più problemi che soluzioni. Possiedo un backgroundworker che esegue una lettura sincrona (in questo caso da serialPort) e viene bloccato per circa 30 secondi in una riga di codice, quindi l'annullamento della sospensione non è la soluzione. Vedo che se l'applicazione viene chiusa a questo punto (con il pulsante croce e Application.Exit()) il processo mantiene zombie per sempre.Backgroundworker abortire

Ho bisogno di un modo per forzare l'interruzione o per interrompere il thread del backgroundworker.

risposta

2

Non sono molto sicuro di ciò che stai cercando di realizzare, ma forse l'evento SerialPort.DataReceived è una soluzione migliore?

Se si è già esperti nell'uso dei thread, non vedo il punto nell'utilizzo di BackgroundWorker. È progettato per le persone che non capiscono i thread in primo luogo.

Inoltre, non mi piace l'idea di interrompere una discussione. Sembra pericoloso e le applicazioni multithread non richiedono più rischi.

+0

ho trovato SerialPort.DataReceived per essere un po 'di confusione in CF, non so se l'impl è meglio in FF. Quello CF usa più thread di quanto ci si aspetterebbe, quindi attenzione. – Quibblesome

+10

Quasi tentato di -1 per il commento su BackgroundWorker; è progettato per far rispettare alcuni standard e effettuare automaticamente il marshalling degli eventi sul thread dell'interfaccia utente, che sono validi motivi per il suo utilizzo; non capire il threading causerà problemi indipendentemente da dove tu vada. –

+0

A meno che non ci sia un modo più semplice per sincronizzare con il thread dell'interfaccia utente da un thread normale ... – Glimpse

2

Non penso che BackgroundWorker supporti l'uccisione del thread. L'annullamento di un'operazione deve essere eseguito nel metodo che esegue il lavoro. Nel tuo caso penso che un filo regolare sarà l'opzione migliore.

3

Il processo non deve diventare uno zombie, poiché il thread di BackgroundWorker è contrassegnato come "background" e deve terminare quando l'interfaccia utente viene chiusa.

+0

Questo è vero poiché BW utilizza la classe ThreadPool dietro le quinte. –

5

Ne ho messo uno che (penso) fa il lavoro. Per favore, fammi sapere se sto bene. Ecco un semplice esempio di come funziona.

Poiché l'operatore in background fa parte del pool di thread, non è necessario interromperlo. Ma possiamo eseguire internamente un thread su cui possiamo permettere che si verifichi una interruzione. Il backgroundWorker quindi viene eseguito fino a quando il thread secondario non è completo o viene segnalato ad esso per interrompere il processo. Il thread di background worker può quindi tornare nel pool di lettura. In genere lo racchiuderò in una classe helper e passerò attraverso il metodo delegate che voglio che il thread in background venga eseguito passato come parametro ed eseguito nel thread secondario.

per favore qualcuno fatemi sapere se im sbattere la testa contro un muro, ma sembra funzionare bene .. Ma questo è il problema con i thread isnt esso .. i risultati variabili che si possono ottenere quando lo si esegue in tempi diversi.

+0

È una soluzione interessante, ma a mio parere sarebbe più efficiente creare una classe che avvolga l'oggetto Thread e l'interazione con esso, e non utilizzare un BackgroundWorker come mediatore. Non c'è davvero alcuna ragione per quello che posso vedere. –

0

si può provare questo:

  backgroundworker.Dispose(); 
      backgroundworker = null; 
      GC.Collect(); //this helps cleans up ram