Рассмотрим гипотетический метод объекта, который делает вещи для вас:Как подождать, когда BackgroundWorker отменит?
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);
}
Но this deadlocks, потому что 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?
Update Люди, кажется, смущен этим вопросом. Они, кажется, думают, что я буду использовать BackgroundWorker как:
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += MyWork;
worker.RunWorkerAsync();
WaitForWorkerToFinish(worker);
Это не его, то есть не, что я делаю, и это не что спрашивают здесь. Если бы это было так, не было бы смысла использовать фонового работника.
Это отлично работает, за исключением одной ошибки. Событие необходимо создать в состоянии «не установлено»: частный AutoResetEvent _resetEvent = новый AutoResetEvent (false); – 2008-09-23 21:17:12