Рассмотрим гипотетический метод объекта, который делает что-то за вас:
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
событие не будет обработано, и это событие не может быть обработано, пока приложение не перейдет в режим ожидания. Приложение не будет бездействовать, пока рабочий не закончит работу. (Плюс, это замкнутый круг - отвратительно.)
Другие добавили, что предлагается включить его в:
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);
Это не то, это не то, что я делаю, и не об этом здесь спрашивают. Если бы это было так, не было бы смысла использовать фонового воркера.