【发布时间】:2019-11-27 18:07:40
【问题描述】:
我正在实现一个需要以下功能的线程:
- 及时响应终止请求
- 发送消息
- 在等待消息时保持对 SendMessage 请求的响应
我最初的消息泵实现使用了GetMessage,比如:
while not Terminated and GetMessage(Msg, 0, 0, 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, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
end;
我发现的问题是MsgWaitForMultipleObjects 在等待时阻塞了线程。因此,当通过SendMessageTimeout 向线程发送消息时,它会超时,而使用GetMessage 时则不会。
想到的解决方案是回到GetMessage 实现,但添加一个计时器以确保WM_TIMER 消息每秒重置循环。
这真的是唯一的方法吗? 似乎应该有一些更好的方法来让线程在等待消息时保持响应。
【问题讨论】:
-
使用第一个消息循环并在终止线程时发布 WM_NULL。如果 GetMessage 被阻塞,它将立即返回。应删除您的要求列表中的第 3 项。当无事可做时,保持清醒是没有意义的。
-
第 3 项是指在使用
MsgWaitForMultipleObjects时如何丢弃SendMessageTimout请求。它需要能够响应这些消息。 -
我的评论中勾勒的解决方案没有问题
-
我同意。我猜你是想说它措辞不好。我已经重新措辞了。
标签: multithreading delphi winapi