I am implementing a thread that needs the following features:
- Promptly responds to termination requests
- Pumps messages
- Remains responsive to SendMessage requests while waiting for a message
My initial implementation of the message pump used GetMessage
like:
while not Terminated and GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
The problem I found with that, is that GetMessage will never return unless there is a message.
Meaning, if there is low message activity, it may be quite a while before it checks Terminated
again.
My second implementation (inspired by this answer) used MsgWaitForMultipleObjects
to wait until a message exists before checking (since it has a timeout)
while not Terminated do
begin
if MsgWaitForMultipleObjects(0, nil^, False, 1000, QS_ALLEVENTS) = WAIT_OBJECT_0 then
begin
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;
The problem I've found with this, is that MsgWaitForMultipleObjects
blocks the thread while it waits. So, when a message is sent to the thread via SendMessageTimeout
, it times out, where it doesn't when using GetMessage
.
The solution that comes to mind is to go back to the GetMessage
implementation, but add a timer to make sure a WM_TIMER
message resets the loop every second.
Is this really the only way to do this? It seems there should be some better way to keep the thread responsive while waiting for messages.