Got strange messages in your queue? Maybe Winforms is using it to synchronize your async code onto the UI thread...
I think the fact that BeginInvoke/Invoke/EndInvoke just work is enough for most people. It know it has been enough for me. I didn't even question why it worked, though I did know it was using the message pump, just not exactly how it was using the message pump. Well tonight I had some time so I stepped through the code as best I could and found some interesting items.
First off a control doesn't necessarily have to be the invoker for it's own events. The invoker can be a parent control, or even the parking window for a particular control. I've seen lots of posts on the newsgroups about parking windows and comments like “What in the hell are they”. I've never seen a parking window launch, EVER, but others claim they show up in taksbars and all manner of other weirdness.
A control with a handle is picked so that the handle can be used to find the thread it was created on and maybe to post a message to said handle in the case we are doing an invoke across a thread boundary. All kinds of information is saved about the call on a special object called a ThreadMethodEntry. They have to put information about the call stack (so they can rebuild your permissions on the remote thread). I found that pretty interesting since I had worried about the possibility of being able to circumvent the security model, but they thought of that and cut me off at the gate. Once the TME is built they toss it into a queue. I was thinking hard about this, why a queue, and not use some other collection where we can add, remove, and index by ordinal and put that ordinal on the message?
Well think about it for a minute. Do you want your methods to operate in sync our out of sync? I'd assume in some sort of synchronization. The windows message pump isn't an immediate beast by any means and it would be possible for someone to throw events in the pump ahead of you. So they use the queue and they synchronize access to the queue, so that all of your events happen in a particular order.
In fact, you could queue up 50 methods and thus have 50 events on the message pump. As soon as the first message comes off the pump, all of your callbacks will execute. I'm not sure how much I really like this, but that is the way it works. It also means that if you queue up more operations in any of your callbacks, they'll happen without waiting for the message. Of course you are on the thread, so why would you do that? Well, in asynchronous operation, you'll find that you can set things, and that they get reset because various property sets initiate windows messages which in turn change your values. You have to be so careful with ordering everything.
I won't bore you with any more of the details. If you are interested in more depth I'm always itching to look at some extra IL.