Considera un metodo ipotetico di un oggetto che fa cose per te:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Come si può attendere l'esecuzione di un BackgroundWorker?
In passato le persone hanno provato:
while (_worker.IsBusy)
{
Sleep(100);
}
Ma questo deadlock si blocca perché IsBusy
non viene cancellato fino a quando l' RunWorkerCompleted
evento non viene gestito e quell'evento non può essere gestito fino a quando l'applicazione diventa inattiva. L'applicazione non diventerà inattiva fino a quando il lavoratore non avrà terminato. (Inoltre, è un circuito affollato - disgustoso.)
Altri hanno aggiunto suggerendo di includerlo in:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Il problema è che i Application.DoEvents()
messaggi attualmente in coda vengono elaborati, causando problemi di rientro (.NET non rientra).
Spero di utilizzare una soluzione che coinvolga gli oggetti di sincronizzazione degli eventi, in cui il codice attende un evento, RunWorkerCompleted
impostato dai gestori eventi del lavoratore . Qualcosa di simile a:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Ma sono tornato al punto morto: il gestore di eventi non può essere eseguito fino a quando l'applicazione diventa inattiva e l'applicazione non sarà inattiva perché sta aspettando un evento.
Quindi, come puoi aspettare che un BackgroundWorker finisca?
Aggiornamento Le persone sembrano essere confuse da questa domanda. Sembrano pensare che userò BackgroundWorker come:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Cioè , non è, cioè non quello che sto facendo, e questo è non ciò che viene chiesto qui. Se così fosse, non avrebbe senso utilizzare un lavoratore in background.