【发布时间】:2010-01-13 10:33:23
【问题描述】:
(我有一个解决这个问题的方法,但这不是我第一次被咬,所以我想弄清楚到底发生了什么。)
- 从我的申请中,我
ShowDialog一个表格。 - 表单上有一个按钮,单击该按钮会调用另一个(非 GUI)线程上的代码。
- 非 GUI 线程通过 Control.Invoke 发回状态(
Pushed然后Released) - 当表单看到
Pushed时,它会调用form.Hide() - 当表单看到
Released时,它会更改按钮的外观。
发生的情况是,有时,但不是每次,非 Gui 线程在尝试发送 Released 时会“卡住”。没有例外,Gui 继续“工作”,但在任何一个方向上都无法与非 Gui 线程进行进一步的通信。
线程的(简化的)调用堆栈如下所示:
System.Threading.WaitHandle.WaitOne()
(...)
System.Windows.Forms.Control.WaitForWaitHandle()
(...)
System.Windows.Forms.Control.Invoke()
(...)
GuiCode.OnStatusChanged()
(...)
NonGuiCode.SetStatus()
如果我将ShowDialog 替换为Show,问题就会消失,但有趣的是,它会变得更好(发生的频率降低),但如果我注释掉执行Hide 的代码,问题不会完全消失Pushed.
更新
感谢nobugz,我发现了死锁(我以前只在数据库中遇到过)!显然用 Control.BeginInvoke 替换 Control.Invoke 解决了这个问题(状态事件有时仍然会“卡住”,但它不会阻止所有后续通信)。
【问题讨论】:
标签: c# .net multithreading invoke