Control.Invoke getting 'stuck' in hidden ShowDialog

醉酒当歌 提交于 2019-12-05 16:01:04

Clearly, you are battling deadlock. That's always around the corner when you use Control.Invoke() instead of BeginInvoke(). It isn't clear to me what trips the deadlock from your post. One red flag is using Hide() on a form that you displayed with ShowDialog(). That normally closes the dialog.

Best thing to do is to debug it. Wait until the deadlock occurs, then use Debug + Break All. Use Debug + Windows + Threads and switch to the UI thread. Look at the Call Stack. If it is not pumping the message loop (Application.Run()) but is stuck somewhere (like the wait handle you appear to be using) then deadlock is the result.

To handle the Control.Invoke() call, the GUI thread has to pump a Windows message, but ShowDialog() is a blocking call, so it can't do that until ShowDialog() returns.

Control.Invoke() is also blocking, and the thread calling it has to wait until the GUI thread picks up the message and handles it to continue. If the code that includes the Control.Invoke() is what enables dismissal of the dialog, then bingo, there's your deadlock.

This is all a bit tricky, because deadlock detectors like SosEx's dlk command can't detect the problem from a dump or WinDgb session - the 'lock' involved in the GUI thread's processing of Control.Invoke() is 'implied', not an actual WaitHandle.

I just encountered what I think is this.

From a GUI thread, invoke onto another GUI thread, and have that thread do ShowDialog. If the user's GUI preferences change (e.g. background rotater), deadlock.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!