2012-10-30 22 views
5

Sto cercando di capire un modo per verificare che un filo BackgroundWorker è vivo (cioè ancora in corso Il filo è essenzialmente implementato come un semplice ciclo infinito:.IsBusy di BackgroundWorker è uguale a "IsAlive"?

while (AllConditionsMet()) 
{ 
    DoSomeMagic(); 
    Thread.Sleep(10000); 
} 

La cosa più vicina a IsAlive() ho trovato finora è la proprietà IsBusy, ma dato che il mio sonno filo() s la maggior parte del tempo, non sono sicuro se questo farà il lavoro

Posso contare su IsBusy a fare:.

if (!myWorker.IsBusy) 
    RestartWorker(); 

o sto chiamando per guai?

+1

se isBusy è falso, Backgroundworker non sta facendo un lavoro, quindi non ci si mette nei guai usando il codice mostrato. Solo il metodo "RestartWorker()" è errato, perché Worker non è stato avviato. Ma è più una questione linguistica che un problema di programmazione. – jAC

+2

Si sta cercando un problema se si implementa il codice all'interno del thread per riavviarsi. Sarebbe meglio, rilevando una condizione di errore, terminando il thread e riavviando un thread completamente nuovo. Altrimenti potresti molto probabilmente avere una situazione di stallo. –

risposta

12

BackgroundWorker.IsBusy è vero finché il gestore eventi DoWork è occupato e il gestore di eventi RunWorkerCompleted non è ancora stato eseguito. Prendi nota della seconda clausola, la proprietà non ti dice se il tuo ciclo è attivo.

Inoltre, nel secondo frammento di codice è presente una condizione di gara abbastanza brutta. IsBusy potrebbe essere vero nell'istruzione if() ma essere falso un nanosecondo più tardi. Il tipo di gara che colpisce una volta al mese. L'intento del codice è difficile da capire dai frammenti così difficili da offrire una soluzione alternativa. Considera solo la creazione di un nuovo oggetto BGW, che non potrà mai gareggiare. Aiuta anche a sbarazzarsi di quel ciclo, un thread che dorme per 10 secondi sta sprecando una risorsa di sistema molto costosa nel non fare nulla. E danneggia lo scheduler del threadpool.

4

Dal docs:

vero, se il BackgroundWorker esegue un'operazione asincrona; altrimenti, false.

Indipendentemente se si dorme il thread di lavoro o no, è ancora facendo qualcosa in modo da utilizzare IsBusy dovrebbe andare bene.

5

Per assicurarsi che il Backgroundworker si fermi davvero, puoi ucciderlo manualmente. Imposta yourBackgroundWorker.WorkerSupportsCancellation = true;. Poi basta fermare il BackgroundWorker con:

yourBackgroundWorker.CancelAsync(); 

Ancora isBusy dovrebbe essere sufficiente a rilevare una corsa/istanza di lavoro del vostro BackgroundWorker.