带有超时的GetMessage

我有一个应用程序,第二个线程在循环中调用GetMessage() 。 在某一时刻,第一个线程意识到用户想要退出应用程序,并通知第二个线程它应该终止。 由于第二个线程停留在GetMessage() ,程序从不退出。 有没有办法等待消息超时? 我也接受其他想法。

编辑:(附加说明)

第二个线程运行代码片段:

 while ( !m_quit && GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } 

第一个线程将m_quit设置为true。

Solutions Collecting From Web of "带有超时的GetMessage"

最简单的方法是在调用GetMessage之前调用UINT_PTR timerId=SetTimer(NULL, NULL, 1000, NULL) 。 它会每秒发送一个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; } 

未经测试,但您可以尝试函数MsgWaitForMultipleObjects而不需要实际的任何对象。

 MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLEVENTS); 

如果如果返回WAIT_TIMEOUT它是一个超时,但如果它返回WAIT_OBJECT_0你可以调用GetMessage保证不被阻止。

但请注意以下几点:

如果在线程调用一个函数来检查队列之后,在消息队列中存在未读的指定类型的输入,则MsgWaitForMultipleObjects不会返回。

所以你必须确保你最后一次调用任何消息函数时没有消息留在队列中,否则你将会遇到一种竞争条件。

可能你最好的选择是用GetMessage替换:

 if (MsgWaitForMultipleObjects(0, NULL, FALSE, timeout, QS_ALLEVENTS) == WAIT_OBJECT_0) { while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) { //dispatch the message } } 

但正如我之前所说,我没有测试,所以我不能确定它是否会工作。

你总是可以做的一件事就是发送被阻塞的线程一个用户定义的消息,它会唤醒它,处理消息,然后返回到循环的顶部。 实际上,完全删除m_quit变量可能是最简单的,而只是向主线程发送一条消息,指出“您现在需要退出”。

希望这可以帮助!

您应该能够使用PostThreadMessage发送退出消息到第二个线程。

例如

 PostThreadMessage(threadid, WM_QUIT, 0, 0); 

您不需要在第二个线程中读取m_quit变量,但是应该检查GetMessage错误以及返回值FALSE/0 ,如果下一条消息是退出消息,则返回该值。

是的。 尝试PeekMessage()代替。 但我认为这不会是完全解决问题的。