Stellen Sie sich eine hypothetische Methode eines Objekts vor, das Dinge für Sie erledigt:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Wie kann man warten, bis ein BackgroundWorker fertig ist?
In der Vergangenheit haben die Leute versucht:
while (_worker.IsBusy)
{
Sleep(100);
}
Aber diese Deadlocks , da IsBusy
wird nicht gelöscht , bis das RunWorkerCompleted
Ereignis behandelt wird, und das Ereignis nicht behandelt werden , bis die Anwendung im Leerlauf geht. Die Anwendung wird erst dann inaktiv, wenn der Worker fertig ist. (Außerdem ist es eine belebte Schleife - widerlich.)
Andere haben vorgeschlagen, es zu kludgen in:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Das Problem dabei ist, Application.DoEvents()
dass Nachrichten, die sich derzeit in der Warteschlange befinden, verarbeitet werden, was zu Problemen beim erneuten Eintritt führt (.NET wird nicht erneut eingegeben).
Ich würde hoffen, eine Lösung mit Ereignissynchronisationsobjekten zu verwenden, bei der der Code auf ein Ereignis wartet - das die RunWorkerCompleted
Ereignishandler des Arbeiters festlegen. Etwas wie:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Aber ich bin zurück zum Deadlock: Der Ereignishandler kann erst ausgeführt werden, wenn die Anwendung inaktiv ist, und die Anwendung wird nicht inaktiv, weil sie auf ein Ereignis wartet.
Wie können Sie also warten, bis ein BackgroundWorker fertig ist?
Update Die Leute scheinen von dieser Frage verwirrt zu sein. Sie scheinen zu glauben, dass ich den BackgroundWorker verwenden werde als:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Das ist es nicht , das ist nicht was ich tue und das ist nicht was hier gefragt wird. Wenn dies der Fall wäre, wäre es sinnlos, einen Hintergrundarbeiter einzusetzen.