(我有一个解决这个问题的方法,但这不是我第一次被咬,所以我试图确切地了解发生了什么。)
- 从我的申请中,我
ShowDialog
有一个表格。 - 表单上有一个按钮,单击该按钮时会调用另一个(非 GUI)线程上的代码。
- 非 GUI 线程通过 Control.Invoke发回状态 (
Pushed
then )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
如果我替换为,问题就会消失,但有趣的是,它会变得更好(发生的频率降低),但如果我注释掉执行onShow
的代码,问题并不会完全消失。Hide
Pushed
更新
感谢nobugz,我发现了死锁(我以前只在数据库中遇到过)!显然用 Control.BeginInvoke 替换 Control.Invoke 解决了这个问题(状态事件有时仍然会“卡住”,但它不会阻止所有后续通信)。