views:

50

answers:

2

When I call Thread.Sleep on the UI thread, does all invoke methods from background thread automatically get queued up in the message pump of the UI thread and processed when it eventually wakes up?

I'm having problems with a winform app that uses a lot of threadpool threads and sometimes the app hangs after locking/unlocking Windows. One guess is there is some deadlock happened on the UI thread. Another is some UI controls are created on background threads. (how can this cause any problem???)

+1  A: 

The rule is, only the thread that creates a UI control should mess with it. That's part of the reason there's a "UI thread" at all -- and it keeps you from having to guess whether you need to Invoke stuff or just do it. (If the event happens from a UI control, it's in the UI thread, so you can just do it. Otherwise, Invoke.) So you want to create your controls in that thread, and let it be the one that handles all the UI as it was intended to.

Your UI thread has one purpose: to handle all the events from the UI in order to keep your app responsive, and to keep it from looking "frozen". Occasionally, it'll be busy (from handling other events), but it should always be either handling an event or waiting for another. Never call Thread.Sleep on the UI thread unless you have a damn good reason and can specifically say why it's not a horrible idea. Just about anything you'd want to do with Thread.Sleep could be handled with timers instead and be much less rickety.

Short version: yes, if the UI thread is doing something (even sleeping), calls to Control.Invoke will almost certainly wait til it's not. If the thread's sleeping, that could be a very long time.

cHao
+1  A: 

Yes, getting a deadlock when unlocking the work station is a pretty infamous Windows Forms threading problem. I never got a good diagnosis for this but I'm fairly sure it is caused by the SystemEvents class. It is a program initialization problem, the class gets initialized on demand when controls start subscribing to its events.

I think the failure mode is creating the first form on a thread other than the program's main thread. You'd get this when, say, you create your own splash screen instead of using the .NET one. Or spinning up a thread that creates its own form instance and starting it too soon. As a result, SystemEvents will fire its events from the wrong thread. The SystemSwitch event is somehow lethal.

So, look at your startup code with a fine-toothed comb. Subscribing to one of the system events in your Main() method before doing anything important ought to be a Q&D fix.

Hans Passant