在基于C ++ / MFC的Windows桌面应用程序中,我有一些我PostThreadMessage的CWinThread工作者。线程是通过AfxBeginThread创建的,它们的消息函数包含如下队列:
UINT WorkerThread(LPVOID arg)
{
// ... init, create pump, flag readyness then pump:
MSG msg;
while ( GetMessage(&msg, NULL, 0, 0) ) {
// Same results with while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
switch ( msg.message ) {
case VALID_MSG1: /*do stuff*/ break;
case VALID_MSG2: /*do stuff*/ break;
case WM_NULL:
// Why do I get this?
// What is the best way to handle it?
// Do not try to filter them out in GetMessage, they will fill the queue!
break;
default: /*log unexpected*/ break;
}
}
}
有时我会收到msg.message == WM_NULL(0)的消息风暴,这让我想知道我是不是做错了。
我最常见到的两个线程之间的一个共同点就是它们使用了WinInet的CInternetSession,CHttpConnection和CHttpFile。也许某个地方他们使用CSocket并在线程上获得额外的消息。
为什么我会将msg.message == WM_NULL或我没有PostMessage的任何其他值传递给此线程的句柄?
我该怎么处理这些消息?像我一样放下它们可以吗?我的工作线程没有GUI,所以我似乎不应该将它们传递给DispatchMessage。
如果我尽可能少地做到这一点,那么消息风暴很快就会消失,事情就会恢复正常。如果我尝试使用GetMessage过滤它们并且从不处理未过滤的消息,则队列将填充这些WM_NULL消息,并且拒绝预期的消息。
我应该扩展并使用CWinThread :: PumpMessage吗? (看起来像矫枉过正。)
这让我觉得我应该使用一些标准的C ++东西来实现我的线程和工作队列,尽管使用PostMessage& PostThreadMessage在代码的其他部分。
更新了帖子,以整合提出的问题和见解的答案。