Sleep(), UI threads and COM do not match

Posted: (EET/GMT+2)

 

We all know the oft-useful Windows API function named Sleep. This little gem allows you to block the executing of your application's current thread for the given number of milliseconds.

However, Sleep is often used to simulate improper waiting on objects. That is, instead of creating an event object for example and then using the WaitForSingleObject API function, you create a loop to poll a global flag, and then use Sleep to wait for, say, one second as not to grab the CPU for yourself only. This is very bad practice, and gets even more so if somebody installs your application on a Terminal Server or Citrix MetaFrame application server.

But, what is less known that sleeping on an UI thread can have very bad consequences, too. This is because system-wide broadcast messages get stuck with your user interface thread, which in turn can stall your whole operating system in the worst case scenario. But what's even worse, you can have problems even if you don't know it. That is because many applications today use OLE, COM or ActiveX routines. Does this ring a bell? It should. Says The Old New Thing:

"Note that many people overlook that calling CoInitialize (possibly indirectly) to initialize a thread for STA creates a hidden window in order to perform marshalling. Consequently, a thread that is running in a single-threaded apartment must pump messages. Failing to do so will result in mysterious system-wide stalls due to the unresponsive window."

Keep this in mind while you program Windows applications! Calling Sleep() has its uses, but it is often called when it shouldn't be. Take heed!