Как правильно ждать, пока BackgroundWorker завершит работу?

Соблюдайте следующий фрагмент кода:

var handler = GetTheRightHandler();
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += OnAsyncOperationCompleted;
bw.DoWork += OnDoWorkLoadChildren;
bw.RunWorkerAsync(handler);

Теперь предположим, что я хочу подождать, покаbw заканчивает работать Какой правильный способ сделать это?

Мое решение таково:

bool finished = false;
var handler = GetTheRightHandler();
var bw = new BackgroundWorker();
bw.RunWorkerCompleted += (sender, args) =>
{
  OnAsyncOperationCompleted(sender, args);
  finished = true;
});
bw.DoWork += OnDoWorkLoadChildren;
bw.RunWorkerAsync(handler);
int timeout = N;
while (!finished && timeout > 0)
{
  Thread.Sleep(1000);
  --timeout;
}
if (!finished)
{
  throw new TimedoutException("bla bla bla");
}

Но мне это не нравится.

Я подумал о заменеfinished флаг с событием синхронизации, установите его вRunWorkerCompleted обработчик и блокировать его позже вместо выполнения цикла while-sleep.

Увы, это неправильно, потому что код может выполняться в контексте синхронизации WPF или WindowsForm, и в этом случае я бы заблокировал тот же поток, что иRunWorkerCompleted работает обработчик, что явно не очень умный ход.

Я хотел бы знать о лучшем решении.

Благодарю.

РЕДАКТИРОВАТЬ:

Постскриптум

Пример кода специально создан для того, чтобы уточнить мой вопрос. Я прекрасно осведомлен о обратном вызове завершения, и все же я хочу знать, как ждать до завершения. Это мой вопрос.Я в курсеThread.Join, Delegate.BeginInvoke, ThreadPool.QueueUserWorkItemи т.д ... Вопрос конкретно оBackgroundWorker.

РЕДАКТИРОВАТЬ 2:

Хорошо, я думаю, будет намного проще, если я объясню сценарий.

У меня есть метод модульного теста, который вызывает некоторый асинхронный код, который, в свою очередь, в конечном итоге включаетBackgroundWorker к которому я могу передать обработчик завершения. Весь код мой, поэтому я могу изменить реализацию, если захочу. Я не собираюсь, однако, заменитьBackgroundWorkerпотому что он автоматически использует правильный контекст синхронизации, так что когда код вызывается в потоке пользовательского интерфейса, обратный вызов завершения вызывается в том же потоке пользовательского интерфейса, что очень хорошо.

В любом случае, возможно, что метод модульного тестирования достигнет конца, прежде чем BW закончит свою работу, что не очень хорошо. Поэтому я хочу подождать, пока BW завершит свою работу, и хотел бы узнать, как лучше всего это сделать.

В нем есть больше частей, но общая картина более или менее такая, как я только что описал.

Ответы на вопрос(10)

Ваш ответ на вопрос