Рассмотрим гипотетический метод объекта, который делает вещи для вас:
public class DoesStuff
{
BackgroundWorker _worker = new BackgroundWorker();
...
public void CancelDoingStuff()
{
_worker.CancelAsync();
//todo: Figure out a way to wait for BackgroundWorker to be cancelled.
}
}
Как можно ждать выполнения BackgroundWorker?
В прошлом люди пытались:
while (_worker.IsBusy)
{
Sleep(100);
}
Но это взаимоблокировки, потому что IsBusy
не очищается до тех пор, пока не будет обработано событие RunWorkerCompleted
, и это событие не сможет получить обрабатывается до тех пор, пока приложение не будет работать. Приложение не будет простаивать до тех пор, пока рабочий не будет выполнен. (Кроме того, это занятый цикл - отвратительный.)
Другие добавили предложение: kludging его в:
while (_worker.IsBusy)
{
Application.DoEvents();
}
Проблема заключается в том, что Application.DoEvents()
приводит к обработке сообщений, находящихся в очереди в очереди, что вызывает проблемы с повторным подключением (.NET не является повторным).
Я хотел бы использовать какое-то решение, включающее объекты синхронизации событий, где код ждет для события - то, что задает обработчик событий RunWorkerCompleted
. Что-то вроде:
Event _workerDoneEvent = new WaitHandle();
public void CancelDoingStuff()
{
_worker.CancelAsync();
_workerDoneEvent.WaitOne();
}
private void RunWorkerCompletedEventHandler(sender object, RunWorkerCompletedEventArgs e)
{
_workerDoneEvent.SetEvent();
}
Но я вернулся в тупик: обработчик событий не может работать до тех пор, пока приложение не станет бездействовать, и приложение не будет простаивать, потому что оно ждет события.
Итак, как вы можете дождаться завершения BackgroundWorker?
Обновление Люди, похоже, смущены этим вопросом. Кажется, они думают, что я буду использовать BackgroundWorker как:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Это не так, это не то, что я делаю, и это не то, что здесь задают. Если бы это было так, не было бы смысла использовать фонового работника.