sách gpt4 ai đã đi

multithreading - 如何保持线程的消息泵 react 性

In lại 作者:行者123 更新时间:2023-12-03 15:49:23 30 4
mua khóa gpt4 Nike

我正在实现一个需要以下功能的线程:

  1. 及时响应终止请求
  2. 推送消息
  3. 在等待消息时保持对 SendMessage 请求的响应

我对消息泵的初始实现使用了 GetMessage, như được hiển thị bên dưới:

while not Terminated and GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;

我发现的问题是,除非有消息,否则 GetMessage 将永远不会返回。这意味着,如果消息事件较少,可能需要相当长的一段时间才能再次检查已终止.

我的第二个实现(受到 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 消息每秒重置循环。

这真的是唯一的方法吗?看来应该有一些更好的方法来让线程在等待消息时保持响应。

1 Câu trả lời

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.

您可以覆盖线程的虚拟 TerminatedSet()方法通过 PostMessage() hoặc PostThreadMessage() 向队列发布消息以“唤醒”GetMessage() 如果被阻止。

或者,让你的线程构造函数创建一个 TEvent对象,并在线程的析构函数中释放它。然后让 TermatedSet() 发出该事件的信号。然后,您的循环可以使用 MsgWaitForMultipleObjects() 同时等待消息队列和事件。返回值将告诉您是否通过消息或事件满足了等待。

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.

SendMessage...() 系列函数将直接将消息传递到目标窗口的消息过程,完全绕过消息队列。因此 MsgWaitForMultipleObjects()(Get|Peek)Message() 永远不会报告来自 SendMessage...() 的已发送消息,仅来自 PostMessage() hoặc PostThreadMessage() của发布消息(或合成消息,如 WM_TIMER,WM_PAINT 等)。但是,当跨线程边界发送消息时,接收线程仍然需要执行消息检索调用(即(Get|Peek)Message()),以便发送消息实际传递给窗口过程。

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.

在线程内,最好使用 waitable timerCòn hơn là WM_TIMER,那么您可以通过 MsgWaitForMultipleObjects() 使用计时器。但实际上,将 GetMessage()WM_TIMER 一起使用与 MsgWaitForMultipleObjects() 与超时一起使用之间几乎没有什么区别,因此没有必要创建计时器浪费系统资源。

关于multithreading - 如何保持线程的消息泵 react 性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59076128/

30 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com