【问题标题】:BackgroundWorker deadlock when using Control.Invoke in DoWork together with ShowDialog在 DoWork 中使用 Control.Invoke 和 ShowDialog 时的 BackgroundWorker 死锁
【发布时间】:2013-01-23 09:18:36
【问题描述】:

我在BackgroundWorker 中运行一项很长的任务,通过ReportProgress 更新用户界面。但是,在这个过程的中间,我需要进行 COM 调用以获取一些数据,并且我认为我需要在 UI 线程上进行。我尝试通过 Control.Invoke 执行此操作。但是,我遇到了僵局。不能在BackgroundWorker 中使用Control.Invoke(与ShowDialog)吗?

我试图简化代码:

        var log = new LogWindowForm();
        worker.DoWork += (sender, args) =>
        {
                creator.LogProgress = (s, i) => worker.ReportProgress(i,s);
                creator.GetMoreDataFunc = (s) => InvokeGetMoreDataOnGuiThread(log, s);
                ...
                var data = GetMoreDataFunc("id:"+id)
        };
        worker.RunWorkerAsync();
        log.ShowDialog();


    private Dictionary<string, string> InvokeGetMoreDataOnGuiThread(Control invokeControl, string id)
    {
        var data = new Dictionary<string, string>();
        Action action = () => data = GetMoreDataFromComObject(mainComObject, id);
        invokeControl.Invoke(action); // deadlock!
        return data;
    }

编辑:

没有例外,UI 会不断更新,但会停止前进。 Break All 显示 Control.Invoke 调用中的工作线程和 ShowDialog 调用中某处的 GUI 线程。

GUI 线程似乎在消息循环中:

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x65 字节

我想这就是 UI 不断更新的原因。 BackgroundWorker 内部是否有一些锁定?

【问题讨论】:

  • 死锁是什么意思?发生什么了?有什么例外吗?
  • 你在GetMoreDataFromComObject()做什么?
  • @Animal 我对 com 对象进行了一些调用,与 GUI 直接无关。它是大型应用程序中的一个插件。
  • @Erno 没有例外,UI 不断更新,但它停止了进展。 Break All 显示 Control.Invoke 调用中的工作线程和 ShowDialog 调用中某处的 GUI 线程。
  • @johv,如果只是调用 COM 对象,为什么需要在 GUI 线程上运行 GetMoreDataFromComObject()

标签: c# winforms backgroundworker deadlock invoke


【解决方案1】:

猜测,因为我不知道 COM 对象做什么或需要什么:

COM 对象需要 UI htread 的原因可能是因为(在大多数情况下)UI 线程被标记为 STA 线程。

如果 COM 对象需要单线程 Appartment,您可以使用标记为 STA 线程的非 UI 线程。这样您就不再需要 UI 线程了。

见:Could you explain STA and MTA?

和:an explanation of STA in .NET

How to make a .NET thread STA or MTAby using an attribute

【讨论】:

  • 我最终切换到直接使用新线程,这很有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 2013-05-24
相关资源
最近更新 更多