我有一个应用程序,第二个线程在循环中调用GetMessage()。在某个时候,第一个线程意识到用户希望退出应用程序,并通知第二个线程它应该终止。当第二个线程被卡在GetMessage()上时,程序永远不会停止。有什么方法可以等待消息超时吗?我也愿意接受其他的想法。
编辑:(附加解释)
第二个线程运行代码片段:
while ( !m_quit && GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}第一个线程将m_quit设置为true。
发布于 2012-06-02 22:11:57
最简单的方法是在调用UINT_PTR timerId=SetTimer(NULL, NULL, 1000, NULL)之前调用GetMessage。它将每秒钟向调用线程发送一条WM_TIMER消息,因此GetMessage将迅速返回。然后,打电话给KillTimer(NULL, timerId)取消它。
更新示例代码:
BOOL GetMessageWithTimeout(MSG *msg, UINT to)
{
BOOL res;
UINT_PTR timerId = SetTimer(NULL, NULL, to, NULL);
res = GetMessage(msg);
KillTimer(NULL, timerId);
if (!res)
return FALSE;
if (msg->message == WM_TIMER && msg->hwnd == NULL && msg->wParam == timerId)
return FALSE; //TIMEOUT! You could call SetLastError() or something...
return TRUE;
}发布于 2012-06-02 22:37:02
没有测试,但是您可以在没有任何对象的情况下尝试函数MsgWaitForMultipleObjects。
MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLINPUT);如果返回WAIT_TIMEOUT,则为超时,但如果返回WAIT_OBJECT_0,则可以使用保证不被阻塞的方式调用GetMessage。
但请注意以下各点:
如果在线程调用函数检查队列后消息队列中存在指定类型的未读输入,则MsgWaitForMultipleObjects不会返回。
因此,您必须确保上次调用任何消息函数时,队列中没有消息,否则会有某种争用条件。
您最好的选择可能是将GetMessage替换为:
if (MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0)
{
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
//dispatch the message
}
}但正如我之前说过的,我没有测试它,所以我不能确定它是否会起作用。
发布于 2012-06-02 22:17:29
您总是可以做的一件事就是向阻塞的线程发送一条用户定义的消息,该消息将导致它醒来,处理该消息,然后返回到循环的顶部。实际上,完全删除m_quit变量,而只向主线程发送一条“您现在就需要退出”的消息可能是最简单的。
希望这能有所帮助!
https://stackoverflow.com/questions/10866311
复制相似问题