【问题标题】:Keep Backgroundworker alive让后台工作者保持活力
【发布时间】:2015-09-03 18:32:43
【问题描述】:

我有一个调用异步方法的BackgroundWorker。 async 方法提供了一个回调参数,让我知道它已经完成。

//Bunch of stuff to prep for the call happens first
SomeAsyncMethodIn3rdPartyDll(callback);
//A few more clean up operations after the call

我遇到的问题是BackgroundWorker 在调用回调之前完成,因此由于线程已死,因此它永远不会被调用。

我当前(工作)的解决方案是在我的 DoWork 方法的末尾添加这个:

      while (keepAlive)
      {
        Application.DoEvents();
        System.Threading.Thread.Sleep(100);
      }

然后,当我收到回调时,我只需将 keepAlive 的值设置为 false。

这看起来很老套,尤其是使用Application.DoEvents() 命令来触发回调。

所以,我想知道的是:有没有更好的方法让线程保持活力?或者,我可以指定我想要处理哪些消息而不是DoEvents(所有消息都处理)?其他解决方案?

【问题讨论】:

  • 嗯,这必须是 COM 组件才能表现得像这样。 BGW 对于此类组件来说是一个非常不利的地方,你真的应该避免它。鉴于它支持回调,常规 UI 线程应该已经足够好了。如果没有,请确保为组件创建an STA thread,以便它拥有一个快乐的家。不要急于杀死它。

标签: c# multithreading backgroundworker


【解决方案1】:

您根本不应该使用BackroundWorker。 BGW 用于在另一个线程中执行 CPU 限制 工作。您正在尝试调用异步操作。完全废弃BGW。直接在 UI 线程中启动异步操作,并在该操作完成后在回调方法中执行您需要执行的任何操作。

如果需要,您可以使用任务并行库将异步操作封装在 Task 中,因为它与 await 关键字结合使用,如果需要,它允许使用更强大的语法来执行异步操作。

【讨论】:

  • 准备调用异步方法需要做很多事情。在 UI 线程上运行它们不是一种选择。我没有过多地研究任务并行库,但是,我可以将异步调用包装到一个任务中并从我的 BGW 线程中等待吗?
  • @MikeH 如果您使用的是 TPL,那么您不需要 BGW,您只需等待准备工作,然后等待异步操作,然后等待清理工作。如果没有 TPL,您将在另一个线程中运行准备工作,然后启动异步工作,然后在回调中启动另一个线程来完成清理工作。这就是异步编程的工作原理。
猜你喜欢
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-21
  • 2011-02-06
  • 2015-12-09
相关资源
最近更新 更多