Domanda

Di recente ho provato a utilizzare il backgroundworker invece di " classic " discussioni e sto realizzando che sta causando, almeno per me, più problemi che soluzioni. Ho un backgroundworker che esegue una lettura sincrona (in questo caso da serialPort) e viene bloccato per circa 30 secondi in 1 riga di codice, quindi la cancellazione in sospeso non è la soluzione. Sto vedendo che se l'applicazione viene chiusa a questo punto (sia con il pulsante trasversale che con Application.Exit ()) il processo mantiene lo zombi per sempre.

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

È stato utile?

Soluzione

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

Se sei già esperto nell'uso dei thread, non vedo il punto nell'uso di BackgroundWorker. È progettato per le persone che non capiscono le discussioni in primo luogo.

Inoltre, non mi piace l'idea di interrompere un thread. Sembra pericoloso e le applicazioni multithread non hanno più bisogno di correre rischi.

Altri suggerimenti

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

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};

backgroundWorker.DoWork += (sender, args) =>
         {                 
                 var thisWorker = sender as BackgroundWorker;
                 var _child = new Thread(() =>
                                               {
                                                   //..Do Some Code

                                               });
                 _child .Start();
                 while (_child.IsAlive)
                 {
                     if (thisWorker.CancellationPending)
                     {
                         _child.Abort();
                         args.Cancel = true;
                     }
                     Thread.SpinWait(1);
                 }                 
         };

 backgroundWorker.RunWorkerAsync(parameter);
 //..Do Something...
backgroundWorker.CancelAsync();

Poiché il lavoratore in background fa parte del pool di thread, non vogliamo interromperlo. Ma possiamo eseguire internamente un thread sul quale possiamo consentire che si verifichi un'interruzione. Fondamentalmente, quindi, backgroundWorker viene eseguito fino a quando il thread figlio non è completo o non viene segnalato per interrompere il processo. Il thread di lavoro in background può quindi tornare nel pool di lettura. In genere lo impaccherò in una classe helper e passerò attraverso il metodo delegato che voglio che il thread in background venga eseguito passato come parametro ed eseguirlo nel thread figlio.

Per favore qualcuno mi faccia sapere se sto sbattendo la testa contro un muro ma sembra funzionare bene .. Ma questo è il problema con i thread non è così ... i risultati variabili che puoi ottenere quando lo esegui in momenti diversi.

Il processo non dovrebbe diventare uno zombi, poiché il thread BackgroundWorker è contrassegnato come " background " e dovrebbe terminare quando l'IU è chiusa.

Non credo 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 thread regolare sarà l'opzione migliore.

Puoi provare questo:

            backgroundworker.Dispose();
            backgroundworker = null;
            GC.Collect(); //this helps cleans up ram
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top