Click to See Complete Forum and Search --> : How does SendMessage work exactly?


ewing
March 19th, 2004, 07:05 AM
Imagine following situation:


Thread A: application main thread, has a window and a window procedure

Thread B: worker thread. Sometimes wants to tell s.th. to the main window, using SendMessage()


Now Thread A is waiting for an event with

WaitForSingleObject()

At this moment thread B calls SendMessage(). What happens?
Will thread B block, because thread A is not processing messages at the moment? Or is there no problem, because window proc is called directly?

In MSDN I've read s.th. like "The system switches to the different thread and calls it's window procedure. Messages sent between threads are processed only, when the receiving thread executes message retrieving code"

This information is not quite clear for me. Who can help?

Thanks in advance.

sephiroth2m
March 19th, 2004, 09:41 AM
I think it means when u send message between threads, u may run into deadlock. That's why M$ recommends using PostMessage, PostThreadMessage, SendNotifyMessage, SendMessageTimeOut in those cases. Also there is at least one article ("Multi threads in GUI", I think so) in MSDN that talks about this.

Myself dot NET
March 19th, 2004, 06:06 PM
Yes, thread B will block until thread A processes the message. The direct calling that you mention only occurs when the window to which you are sending the message is owned by the calling thread (thread B). As a solution, you can either have thread B use one of the other message sending functions that does not block (like PostMessage), or more preferably, have thread A use the MsgWaitForMultipleObjects function so that it can still process messages while waiting on a kernel object. I say this is more preferable because a thread that creates windows should use this function in general when waiting on objects.

sephiroth2m
March 20th, 2004, 08:52 AM
But i don't think MsgWaitForMultipleObjects could resolve the problem completly. Consider when thread A does not wait for objects, but calls SendMessage to thread B, or yields control by calling DialogBox... in its mess. handler instead.

Myself dot NET
March 20th, 2004, 08:00 PM
When a thread is blocking in SendMessage, it can still process messages, and when DialogBox is called, a message loop is entered, so messages can still be processed.

So, yes, what I proposed does solve the problem completely.

sephiroth2m
March 21st, 2004, 02:44 AM
Have you tried examining into that?
Consider when thread B, in its WM_CREATE, SendMessage to thread A, and depends on how A returns to invoke the start-up routine. What happens if thread A finds an error in its message handler, and displays a message box? Whether thread B can still process other messages? If it can, so really a bad situation it is.

Myself dot NET
March 21st, 2004, 03:18 AM
First, since when is thread B receiving messages? It doesn't create any windows, so it will not receive WM_CREATE.

My point was, if thread A is blocking in a SendMessage() call of its own or is displaying a dialog box when thread B sends it a message, it will still be able to process that message.

Now, the secondary issue as to what will happen when thread A is processing a message is dependent upon the application. If you don't want it to display a message box to the user, don't write that code! Throwing out these useless what if's doesn't really address the original issue. I mean, what if thread A caused a memory access violation and crashed the application? Who cares? That's not the question at hand.

sephiroth2m
March 21st, 2004, 07:42 PM
For simply all I want to say was: Thread B does have a chance of being blocked if it calls SendMessage to thread A, whether thread A calls MsgWaitForMultipleObjects or not. And if you dont think so, you should make a test.

Myself dot NET
March 22nd, 2004, 02:30 AM
Ah, I see what you mean now. Yes, you are absolutely correct, thread B will still block while thread A is processing the message. When I suggested MsgWaitForMultipleObjects, I was referring to his question
Will thread B block, because thread A is not processing messages at the moment?
Thread A would not be processing messages at all if it called WaitForSingleObject(). MsgWaitForMultipleObjects() allows it to continue processing messages.