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.

Community
  • 1
  • 1
vietvoquoc
  • 813
  • 1
  • 10
  • 23
  • This is written in the context of Delphi, but you can replace `ProcessMessages` with `DoEvents` and the rest is otherwise the same : http://stackoverflow.com/a/25182276/327083 – J... Jul 15 '16 at 08:32
  • Possible duplicate of [UI Thread both running message pump AND executing code?](http://stackoverflow.com/questions/9963327/ui-thread-both-running-message-pump-and-executing-code) – Richard Ev Jul 15 '16 at 08: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. – Luaan Jul 15 '16 at 08: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. – Matthew Watson Jul 15 '16 at 08: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! – vietvoquoc Jul 15 '16 at 09:01
  • @Matthew Watson, i read this topic before post my topic and BrendanMcK said "Perhaps the place to start is to realize that "the message loop" isn't a thing as such; it's really just something that a thread does." so that i thought the message loop code will run on UI thread or another thread. – vietvoquoc Jul 15 '16 at 09:07

2 Answers2

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.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • 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. – vietvoquoc Jul 18 '16 at 06:31
  • 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. – Lasse V. Karlsen Jul 18 '16 at 06:52
  • 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. – Lasse V. Karlsen Jul 18 '16 at 06:53
  • thank you so much because took time to explain for me, very concise and clear. – vietvoquoc Jul 19 '16 at 08:59
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.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325