(I have a workaround for this problem, but it's not the first time I've been bitten, so I'm trying to understand exactly what's going on.)
- 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
thenReleased
) via a Control.Invoke - When the form sees the
Pushed
, it invokesform.Hide()
- When the form sees the
Released
, it changes the appearance of the button.
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()
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
.
Update
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).