5

I am so confusing about how message loop in winforms work. I am working on windows form and i knew when calling Application.Run(myform), so it will create a message queue and message loop and then display my Form and start retrieving message in message queue to dispatch.

I read some topics and still do not understand how message loop work behind the scene, UI Thread both running message pump AND executing code? and How does the message loop use threads?

My question is: Does message loop will run on UI thread. If yes why it do not block UI thread?

If question not clear please let me know, sorry because my english is bad.

6
  • This is written in the context of Delphi, but you can replace ProcessMessages with DoEvents and the rest is otherwise the same : stackoverflow.com/a/25182276/327083 Commented Jul 15, 2016 at 8:32
  • Possible duplicate of UI Thread both running message pump AND executing code? Commented Jul 15, 2016 at 8:34
  • Just a note - the message queue is already there. The main thing Application.Run does is start the message loop. Which really is just an almost-endless loop that takes messages from the queue and processes them. The message loop isn't exactly the UI thread, but in 99% of cases, you can consider them the same thing. All those UI actions like clicking a button come as a message to the queue, are taken in the loop and processed in your code. This is because the Windows windowing system is message/event based - the UI thread doesn't actively poll for input state, it waits for a message. Commented Jul 15, 2016 at 8:39
  • "Does message loop will run on UI thread. If yes why it do not block UI thread?" The message loop IS the UI thread, so the question doesn't really make sense in that context. Commented Jul 15, 2016 at 8:47
  • @Richard Everett, Sorry i read that topics before post this topic, it is really short and i do not get the point. in reality i need more explanation! Commented Jul 15, 2016 at 9:01

2 Answers 2

5

The message loop can broadly be explained with this example code:

Message message;
while (PeekMessage(out message))
    ProcessMessage(messae);

And yes, this "blocks" the thread. The thread will always either be waiting for a message to appear (PeekMessage should return when a message is ready) or processing the message.

What is important to know is that this is the magic that doesn't block UI. Anything the UI needs to respond to is handled as a message.

The very important part is that to avoid blocking the UI, whatever ProcessMessage does to process a single message should never take too long.

If the user clicks on a button, this will be handled as a message. As part of processing that message, your event handler will be called. If that event handler starts doing something lengthy, you're not returning back to the message loop, and thus it stops processing messages while your button click event handler is running.

So yes, the message loop runs on the UI thread. And yes, it also blocks the UI thread, but the fact that it keeps running means that it isn't blocking the UI.


Inspired by the comment I thought I should post an analogy that explains why the loop works.

Think of a local Deli serving food. Some food is ready-made, just has to be sold to the consumer, and some food has to be prepared on demand.

There are several typical operations happening in this Deli:

  1. An order for food has to be taken
  2. The food has to be prepared, or fetched
  3. The food has to be given to the consumer

Now, consider a Deli with just 1 person behind the desk.

This person does these three operations for each and every consumer. Obviously, if one consumer orders food that has to be prepared then and there, the rest of the consumers will have to wait.

On the other hand, if those orders can be given to a chef, a colleague of the order-taking-employee, then orders will be taken much faster.

In Windows, the message loop is this order-taking-employee, and only him.

As part of processing an order (a message), this guy will have to go check on someone else, and then wait, before taking the food (the results) back to the consumer. Any lengthy processing thus slows down processing of this queue.

On the other hand, if that "someone else" simply says, you go back to the queue and tell the consumer that he will get the food when it is ready, then the queue will be moving, even though someone is now waiting for their food.

This is the typical thread or asynchronous processing that is introduced in order to keep the UI responsive.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank for help but could you elaborate on this words "the fact that it keeps running means that it isn't blocking the UI.". So it mean the reason we feel UI not freezing because message loop run infinite? and if we do something like Thread.Sleep(1000) in event handler is the same with function ProcessMessage(message) execute the code take long time? Thank you.
Yes, that is entirely correct. If you do anything as part of handling a message that takes a lot of time, then that code will have to complete before it returns back to the message loop. If messages comes in from the operating system and windowing system in that time, they will simply be queued up and not processed.
A simple analogy is to think about someone that stands at the ordering desk at a local deli. If all he is doing is taking the orders, the queue for people to give him the orders will go by fast. Yes, they will at some point have to wait for the food but that queue is moving fast. If he's also going to make the food, then that queue will go by slower. In Windows, the speed of this queue is directly related to how responsive the user interface fells for the user. A typical trick to get the UI to feel responsive yet do expensive thing is to hire a chef (thread) and move the queue fast.
thank you so much because took time to explain for me, very concise and clear.
1

Does the message loop run on the UI thread?

Yes. It does.

If yes why it do not block UI thread?

You should see the message loop as endless loop: it keeps running forever. Whenever there is a message in the queue to be handled, it picks it up and executes it. That can be a button that is clicked. At that time the button is notified about the event and it will run the code associated to it, for example your button_Click event handler. If you put Thread.Sleep(10000) in it you will notice it will block the entire application for the duration of that sleep (10 seconds). You can't resize, redraw or do anything else because the message loop is blocked too. Once the event handler has ended, it will continue to pick up the next message from the queue.

2 Comments

thank you so much because help me understand more about how winforms work behind the scene.
Actually the message loop does block the UI thread. If it wouldn't, then the CPU would consume 100% of the processing power inside the endless loop. Instead, the UI thread will be blocked and when a message enters the message queue, it will be woken up again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.