在隐藏的ShowDialog Control.Invoke得到'卡' [英] Control.Invoke getting 'stuck' in hidden ShowDialog

查看:210
本文介绍了在隐藏的ShowDialog Control.Invoke得到'卡'的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我有一个解决这一问题,但它不是我第一次被咬伤,所以我想明白到底发生了什么事。)

  • 从我的申请,我的ShowDialog 的形式。
  • 在形式是一个按钮,当另一个(非GUI)线程点击调用code。
  • 非GUI线程发回的状态(然后发布)通过Control.Invoke
  • 在当前的形式看到,它调用 form.Hide()
  • 在当前的形式看到发布,它改变了按钮的外观。
  • From my application, I ShowDialog a form.
  • On the form is a button, which when clicked calls code on another (non-Gui) thread.
  • The non-GUI thread sends back statuses (Pushed then Released) via a Control.Invoke
  • When the form sees the Pushed, it invokes form.Hide()
  • When the form sees the Released, it changes the appearance of the button.

什么情况是,有时,但不是每次,非GUI线程被'卡'尝试发送发布。无例外,在桂进行'工作',但与非桂螺纹没有进一步的通信是可能的,在任一方向。

What happens is that sometimes, but not everytime, the non-Gui thread gets 'stuck' trying to send the Released. No exceptions, the Gui carries on 'working', but no further communication with the non-Gui thread is possible, in either direction.

(简化)调用堆栈的线程看起来是这样的:

The (simplified) callstack for the thread looks like this:

System.Threading.WaitHandle.WaitOne()
(...)
System.Windows.Forms.Control.WaitForWaitHandle()
(...)
System.Windows.Forms.Control.Invoke()
(...)
GuiCode.OnStatusChanged()
(...)
NonGuiCode.SetStatus()

该问题消失,如果我取代的ShowDialog 显示,但 - 有趣的是 - 它变得更好(发生少常),但并没有完全消失,如果我注释掉code,做了隐藏

The problem goes away if I replace ShowDialog with Show, but - interestingly - it gets better (happens less often) but doesn't completely go away if I comment out the code that does the Hide on Pushed.

更新

感谢<一href="http://stackoverflow.com/questions/2055960/control-invoke-getting-stuck-in-hidden-showdialog/2056427#2056427">nobugz,我发现死锁(我只见过它在数据库中之前)!与Control.BeginInvoke显然取代Control.Invoke解决了这个问题(status事件仍然被'卡'的时候,但是它并没有阻止随后的所有通信)。

Thanks to nobugz, I've discovered deadlock (I'd only ever met it in databases before)! Apparently replacing Control.Invoke with Control.BeginInvoke solves this problem (the status event still gets 'stuck' sometimes, but it doesn't block all following communications).

推荐答案

显然,你是对抗僵局。这总是在拐角处时,使用Control.Invoke()而不是的BeginInvoke()。目前尚不清楚对我从您的文章是什么车次的僵局。一个红色标志使用隐藏(),您使用ShowDialog的显示形式()。通常关闭对话框。

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.

做的最好的事情就是进行调试。等到发生死锁,然后使用调试+打破一切。使用调试+的Windows +线程并切换到UI线程。看看调用堆栈。如果不抽消息循环(Application.Run()),但被卡住的地方(如等待句柄,你似乎使用),那么僵局的结果。

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.

这篇关于在隐藏的ShowDialog Control.Invoke得到'卡'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆