gpt4 book ai didi

.net - 如何正确等待BackgroundWorker完成?

转载 作者:行者123 更新时间:2023-12-03 07:38:06 26 4
gpt4 key购买 nike

观察以下代码:

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 相同的线程。 handler 继续运行,这显然不是很明智的举动。

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

谢谢。

编辑:

附注

  • 示例代码是故意为了澄清我的问题而设计的。我完全知道完成回调,但我想知道如何等待完成。这就是我的问题。
  • 我知道 Thread.Join , Delegate.BeginInvoke , ThreadPool.QueueUserWorkItem等等...问题具体是关于 BackgroundWorker .

编辑2:

好吧,我想如果我解释一下这个场景会容易得多。

我有一个单元测试方法,它调用一些异步代码,而这些代码最终会调用 BackgroundWorker我可以向其传递完成处理程序。所有代码都是我的,因此如果我愿意,我可以更改实现。但是,我不会替换 BackgroundWorker ,因为它会自动使用正确的同步上下文,因此当在 UI 线程上调用代码时,会在同一 UI 线程上调用完成回调,这非常好。

无论如何,单元测试方法有可能在 BW 完成工作之前就结束了,这是不好的。所以我想等到 BW 完成并想知道最好的方法。

还有更多的部分,但总体情况或多或少像我刚才描述的那样。

最佳答案

尝试使用 AutoResetEvent 类,如下所示:

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() 提供指定超时时间的参数。

注意:此代码几乎是 Fredrik Kalseth 的副本。回答similar question .

关于.net - 如何正确等待BackgroundWorker完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1333058/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com