我正在实现一个需要以下功能的线程:
- 迅速响应终止请求
- 抽取消息
- 在等待消息时保持对SendMessage请求的响应
我最初对消息泵的实现使用了GetMessage
,例如:
while not Terminated and GetMessage(Msg,0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
我发现的问题是,除非有消息,否则GetMessage将永远不会返回。
这意味着,如果消息活动较少,则可能需要一段时间才能再次检查Terminated
。
我的第二个实现(受this answer启发)使用MsgWaitForMultipleObjects
等到消息存在后再检查(因为它有超时)
while not Terminated do
begin
if MsgWaitForMultipleObjects(0,nil^,False,1000,QS_ALLEVENTS) = WAIT_OBJECT_0 then
begin
while PeekMessage(Msg,PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;
我发现的问题是MsgWaitForMultipleObjects
在等待线程时阻塞了线程。因此,当一条消息通过SendMessageTimeout
发送到线程时,它超时了,而在使用GetMessage
时却没有。
想到的解决方案是返回到GetMessage
实现,但是添加一个计时器以确保WM_TIMER
消息每秒重置一次循环。
这真的是唯一的方法吗? 似乎应该有一些更好的方法来使线程在等待消息时保持响应。