У меня есть внешняя библиотека, в которой есть метод, который выполняет долгосрочную задачу в фоновом потоке. Когда это сделано, оно запускает событие Completed в потоке, который запускает метод (обычно в потоке пользовательского интерфейса). Это выглядит так:
public class Foo
{
public delegate void CompletedEventHandler(object sender, EventArgs e);
public event CompletedEventHandler Completed;
public void LongRunningTask()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(5000);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (Completed != null)
Completed(this, EventArgs.Empty);
}
}
Код, который вызывает эту библиотеку, выглядит следующим образом:
private void button1_Click(object sender, EventArgs e)
{
Foo b = new Foo();
b.Completed += new Foo.CompletedEventHandler(b_Completed);
b.LongRunningTask();
Debug.WriteLine("It's all done");
}
void b_Completed(object sender, EventArgs e)
{
// do stuff
}
В методе button1_Click, после того, как я вызываю b.LongRunningTask (), событие Completed запускается через 5 секунд в потоке пользовательского интерфейса, я обновляю пользовательский интерфейс и все отлично, так как мне не приходится иметь дело с маршалингом в нужную нить.
Однако теперь мне нужно, чтобы процесс был синхронным (без изменения внешней библиотеки). Другими словами, после того, как я запускаю метод .LongRunningTask, следующее значимое утверждение в этом методе должно сработать после завершения .LongRunningTask.
Я пытался сделать это с EventWaitHandle (например, сделать WaitOne после вызова LongRunningTask, а затем сбросить его в событии Completed, но это просто блокирует все).
Есть ли в .NET Framework метод, позволяющий мне это сделать?