【发布时间】: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