Ben*_*jol 5 .net c# multithreading invoke
(我有解决这个问题的方法,但这不是我第一次被咬,所以我试图确切地了解发生了什么。)
ShowDialog一张表格。Pushedthen )ReleasedPushed,它会调用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()
Run Code Online (Sandbox Code Playgroud)
ShowDialog如果我替换为,问题就会消失,但是 - 有趣的是 - 它会变得更好(发生的频率较低),但如果我注释掉执行onShow的代码,问题不会完全消失。HidePushed
更新
感谢nobugz,我发现了死锁(我以前只在数据库中遇到过它)!显然,用 Control.BeginInvoke 替换 Control.Invoke 可以解决此问题(状态事件有时仍然“卡住”,但它不会阻止所有后续通信)。
显然,您正在与僵局作斗争。当您使用 Control.Invoke() 而不是 BeginInvoke() 时,这种情况总是会发生。我不清楚是什么导致了你的帖子陷入僵局。一个危险信号是在使用 ShowDialog() 显示的窗体上使用 Hide()。这通常会关闭对话框。
最好的办法就是调试它。等到死锁发生,然后使用 Debug + Break All。使用 Debug + Windows + Threads 并切换到 UI 线程。查看调用堆栈。如果它没有泵送消息循环(Application.Run()),而是卡在某个地方(例如您似乎正在使用的等待句柄),那么就会导致死锁。
| 归档时间: |
|
| 查看次数: |
3570 次 |
| 最近记录: |