直到BackgroundWorker的完成如何正确地等待? [英] How to wait correctly until BackgroundWorker completes?

查看:733
本文介绍了直到BackgroundWorker的完成如何正确地等待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意下面这段code:

Observe the following piece of code:

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

现在假设我要等到体重工作完毕。什么是正确的方法,这样做?

Now suppose I want to wait until bw finishes working. What is the right way to do so?

我的解决办法是这样的:

My solution is this:

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");
}

但我不喜欢它。

But I do not like it.

我已经考虑了同步事件替换完成标记,在 RunWorkerCompleted 处理程序设置和阻塞它以后而不是做的,而睡眠循环。

I have considered replacing the finished flag with a synchronization event, set it in the RunWorkerCompleted handler and block on it later instead of doing the while-sleep loop.

唉,这是错误的,因为code可在WPF或WindowsForm的同步上下文中运行,在这种情况下,我会阻塞在同一个线程的 RunWorkerCompleted 处理器上运行,这显然不是很明智的举动。

Alas, it is wrong, because the code may run in the WPF or WindowsForm synchronization context, in which case I would block the same thread as the RunWorkerCompleted handler runs on, which is clearly not very smart move.

我想知道一个更好的解决方案。

I would like to know of a better solution.

感谢。

编辑:

P.S。

  • 在该示例code是如此做作刻意澄清我的问题。我完全知道完成回调,但我想知道如何等到完成。这是我的问题。
  • 我知道的Thread.join Delegate.BeginInvoke ThreadPool.QueueUserWorkItem的,等等...现在的问题是专讲的BackgroundWorker
  • The sample code is so contrived intentionally to clarify my question. I am perfectly aware of the completion callback and yet I want to know how to wait till completion. That is my question.
  • I am aware of Thread.Join, Delegate.BeginInvoke, ThreadPool.QueueUserWorkItem, etc... The question is specifically about BackgroundWorker.

编辑2:

OK,我想这会容易得多,如果我解释的场景。

OK, I guess it will be much easier if I explain the scenario.

我有一个单元测试方法,该方法调用某些异步code,从而最终啮合的BackgroundWorker 来这我能够通过完成处理程序。所有code是我的,这样我就可以改变的执行,如果我想。 我不但是去,以取代的BackgroundWorker ,因为它会自动使用正确的同步环境,这样,当code调用在UI线程完成回调函数被调用相同的UI线程,这是非常不错的。

I have a unit test method, which invokes some asynchronous code, which in turn ultimately engages a BackgroundWorker to which I am able to pass a completion handler. All the code is mine, so I can change the implementation if I wish to. I am not going, however, to replace the BackgroundWorker, because it automatically uses the right synchronization context, so that when the code is invoked on a UI thread the completion callback is invoked on the same UI thread, which is very good.

无论如何,这是可能的,单元测试方法击中端的BW完成其工作,这是不好的之前。所以,我希望等到BW完成,想知道它的最好办法。

Anyway, it is possible that the unit test method hits the end before the BW finishes its work, which is not good. So I wish to wait until the BW completes and would like to know the best way for it.

有更多件,但总的情况是像我刚才描述的更多或更少。

There are more pieces to it, but the overall picture is more or less like I have just described.

推荐答案

尝试使用的AutoResetEvent类是这样的:

Try using the AutoResetEvent class like this:

var doneEvent = new AutoResetEvent(false);
var bw = new BackgroundWorker();

bw.DoWork += (sender, e) =>
{
  try
  {
    if (!e.Cancel)
    {
      // Do work
    }
  }
  finally
  {
    doneEvent.Set();
  }
};

bw.RunWorkerAsync();
doneEvent.WaitOne();

注意:您应该确保 doneEvent.Set()被称为无论发生什么事情。你也可能需要提供 doneEvent.WaitOne()有一个参数指定超时时间。

Caution: You should make sure that doneEvent.Set() is called no matter what happens. Also you might want to provide the doneEvent.WaitOne() with an argument specifying a timeout period.

注意::此code是pretty的的弗雷德里克Kalseth多副本回答一个<一个href="http://stackoverflow.com/questions/123661/net-how-to-wait-for-a-backgroundworker-to-cancel">similar问题。

Note: This code is pretty much a copy of Fredrik Kalseth answer to a similar question.

这篇关于直到BackgroundWorker的完成如何正确地等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆