Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this possible: OnPaint processed while in WaitOne

Tags:

I have a ManualResetEvent. At one point, I wait on that event using WaitOne. To my amazement, I received an OnPaint event while in the WaitOne. This happens quite often too.

The stack trace looks like this:

alt text

I understood that a WaitOne would block the current thread and would not allow any other code to be executed until the event fires.

Could someone explain what happens here?

like image 272
Pieter van Ginkel Avatar asked Dec 27 '10 16:12

Pieter van Ginkel


1 Answers

This is by design. The CLR honors the contract of a single-threaded apartment (STA). The main thread of a GUI app is STA as is required in Windows programming, the [STAThread] attribute on the Main() method ensures that.

Hard rules for an STA thread are that it must pump a message loop (like Application.Run) and can never block. Blocking an STA thread is highly likely to cause deadlock when background threads use any COM apartment threaded objects. There are many of them, the clipboard and WebBrowser are common ones you'll encounter in a .NET program. Many less visible ones as well, available as .NET wrapper classes.

The CLR ensures blocking can't cause deadlock by pumping a message loop when you use the lock statement or call the Wait method of the synchronization classes. Or Thread.Join(). That message loop dispatches the WM_PAINT message, causing the Paint event to run.

You need to restructure your program to ensure this doesn't cause a problem. Pretty important to focus on not blocking the main thread at all. It is very rarely needed when you have, say, the BackgroundWorker class or Control.BeginInvoke() at your disposal. For some kind of odd reason the Mutex class doesn't do this kind of pumping, that could be another way. Although deadlock is lurking around the corner if you do.

like image 186
Hans Passant Avatar answered Oct 06 '22 00:10

Hans Passant