Rozważ hipotetyczną metodę obiektu, który działa za Ciebie:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Jak można czekać, aż BackgroundWorker zostanie ukończony?
W przeszłości ludzie próbowali:
while (_worker.IsBusy)
{
Sleep(100);
}
Ale to zakleszczenie , ponieważ IsBusy
nie jest czyszczone, dopóki nie RunWorkerCompleted
zostanie obsłużone zdarzenie, a to zdarzenie nie może zostać obsłużone, dopóki aplikacja nie przejdzie w stan bezczynności. Aplikacja nie będzie bezczynna, dopóki pracownik nie skończy. (Poza tym jest to zajęta pętla - obrzydliwa.)
Inni dodali sugestię umieszczenia go w:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Problem polega na tym, że Application.DoEvents()
powoduje przetwarzanie komunikatów znajdujących się w kolejce, co powoduje problemy z ponownym wejściem (.NET nie jest ponownie wprowadzany).
Chciałbym użyć rozwiązania obejmującego obiekty synchronizacji zdarzeń, w których kod czeka na zdarzenie - ustawiane przez RunWorkerCompleted
programy obsługi zdarzeń pracownika . Coś jak:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Ale wracam do impasu: program obsługi zdarzeń nie może działać, dopóki aplikacja nie przejdzie w stan bezczynności, a aplikacja nie przejdzie w stan bezczynności, ponieważ czeka na zdarzenie.
Jak więc możesz czekać na zakończenie pracy w tle?
Aktualizacja Ludzie wydają się być zdezorientowani tym pytaniem. Wydaje się, że myślą, że będę używać BackgroundWorker jako:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
To jest nie to, że to nie to, co robię, a to nie to, co jest proszony jest tutaj. Gdyby tak było, nie byłoby sensu korzystać z pracownika w tle.