Why do messages posted by PostThreadMessage disappear?


The only thread message you can meaningfully post to a thread displaying UI is WM_NULL, and even then, it’s only because you want to wake up the message loop for some reason.

A common problem I see is people who use PostThreadMessage to talk to a thread that is displaying UI and then wonder why the message never arrives.

Oh, the message arrived all right. It arrived and then was thrown away.

This is actually a repeat of an earlier entry with the title Thread messages are eaten by modal loops, but I’m repeating it with a better subject line to help search engines.

But since I’m here, I may as well augment the existing article.

Obvious places where you have modal loops on a UI thread are functions that are explicitly modal like DialogBox or MessageBox or TrackPopupMenuEx(TPM_RETURNCMD) or DoDragDrop. But there are less obvious modal loops, like the modal loop that runs when you click on the caption bar and hold the button or the modal loop that runs when COM is waiting for a cross-thread call to complete.

And since you don’t control those modal loops, when they call DispatchMessage, your thread message will simply be thrown away.

If you need to communicate reliably with a thread that also displays UI, then create a hidden window and send or post messages to that window.

Comments (8)
  1. nathan_works says:

    Why post message for IPC ? I come from a more multi-platform world, and am continually amazed that when IPC is needed, all that the win32 programmers can do is post/send message. When I point out that I have no UI, no window, no dialog, and no desire to create one, they are stumped. Why do folks use post message so often for IPC when there are better (IMO) methods ?

  2. Josh says:

    @nathan_works:

    Reasons:

    1. Because it’s there. IPC is annoying to build from scratch, so the fact that window messages do most of the work for you is a big plus.  The window is a small price to pay for an otherwise simple IPC system.
    2. Stateless.  It requires no synchronization to prevent data corruption. Unlike some of the other solutions (e.g. shared memory), bad coding by one method is generally less dangerous.  If a single method, in either program, fails to lock the memory before working with it, you get data corruption and both programs will probably die and/or misbehave.

    3. It’s fire and forget; once you’ve sent the message along, you rarely need to deal with it again, so it’s ideal for the producer-consumer scenario.  Pipes can be the same way, and are appropriate if a large amount of data is being exchanged between a small number of processes, but for lots of short messages with different recipients, it can get expensive to maintain all the caches.

    4. You can define IPC "APIs" relatively clearly.  This is related to point 2.  An app that expects others to send it messages can publish an "API" of messages it accepts.  This is flat out impossible to do in a stable way with shared memory (you don’t want the 3rd party app to crash your program if it fails to adhere to lock protocol).  Pipes require knowledge of who will be connecting to them; you could use another mechanism to trigger the dynamic creation of the pipe, but now you need another IPC mechanism to communicate the need for a new pipe, and you essentially require a stateful system.  With messages, any number of producers can arise, send messages, and depart throughout the life of the program, and the program need not do anything to deal with each new producer.

    5. You need it already anyway.  If you’re taking input from the user, they’ll be arriving as window messages.  So the additional cost to receive IPC messages is small.

    Don’t get me wrong, it’s not perfect.  But for stateless, API-based IPC, it’s one of the best options.

  3. Sunil Joshi says:

    This particular MSDN page is quite illuminating on the issue of IPC:

    http://msdn.microsoft.com/en-us/library/aa365574(VS.85).aspx

    It appears that since the days of Win16 the hammer has been supplemented by many (better) alternatives.

    [The problem is that the non-message-based ones are hard to incorporate into a UI thread. -Raymond]
  4. nathan_works says:

    I should add, not as a rebuttal, but as clarifying..

    95% of the time, the win32 guys I work with post a message as a way to (eventually) wake a thread or tell a thread that’s work to do. Events/mutex/semaphore (see, I’ve learned that part of win32 :) work much better with less overhead.

    And for your point #5, rarely am I writing code that deals with input from users. Usually it’s a service of some sort.

  5. Josh says:

    RPC, clipboard, and DDE all seem to provide the same basic features as windows messages (while "Data Copy" *is* a windows message). Mailslots and  (UDP) sockets could be used the same way but they don’t seem much cleaner.  Not sure on COM; I learned a little of it while working at MS, but IPC in my product was all windows messages (much of it was legacy code from the mid 90s and a complete redesign offered little).  Of course, they all lack one small "feature": freebie inclusion.  As my previous post noted (point #5), you’re already using it to receive user input, so in cases where IPC is not the core focus of the program, you may as well use window messages and save yourself some code.

  6. ulric says:

    hey, @nathan_works, who mentioned IPC?  (I assume we mean inter process communication)  I think the most common case for posting message between threads in applications is from worker thread to the UI thread, not between process.  Often to warn of an error that must be displayed in the UI thread, or update some indicator.

    Programmers-by-Google often end up using PostThreadMessage, when they should be using PostMessage with a HWND instead, as this article states.

    Btw if you don’t have a UI thread, this article was not really for you. You can re-write something equivalent to message queues in another way, but the message queue is already there.  And often you might need to respond to some system message eventually anyway.

    Personally, I haven’t come across people using messages to ‘wake up a thread’, but I guess it depends on what people are working on.  

    All the documentation documentation and samples I’ve come across for threading in Win32 show how to wake up threads with events.  If there the worker thread is pumping message, I would think it is truly because it needs to for some other reason than just waking up.

  7. Arno says:

    Is it o.k. to post WM_QUIT to a UI thread? PostQuitMessage() would be nicer, but can only called in-thread.

    [See earlier article. -Raymond]
  8. Anonymous Coward says:

    I think this bit from the Platform SDK is relevant to the article:

    Message-Only Windows

    A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.

    To create a message-only window, specify the HWND_MESSAGE constant or a handle to an existing message-only window in the hWndParent parameter of the CreateWindowEx function. You can also change an existing window to a message-only window by specifying HWND_MESSAGE in the hWndNewParent parameter of the SetParent function.

    To find message-only windows, specify HWND_MESSAGE in the hwndParent parameter of the FindWindowEx function. In addition, FindWindowEx searches message-only windows as well as top-level windows if both the hwndParent and hwndChildAfter parameters are NULL.

Comments are closed.