我正在调用AfxBeginThread并使用CWinThread在我的MFC应用程序中启动UI线程。
我注意到如果我的主线程在CWinThread :: InitInstance()函数返回之前尝试PostThreadMessage()到我的新线程,那么PostThreadMessage()将返回错误:无效的线程句柄。
我的猜测是,在InitInstance返回之后才会设置新线程上的消息泵。我在AfxBeginThread上看到的示例代码和我读过的文档并没有很好地解释这种行为,或者显示了一个等待线程初始化的模式。
在InitInstance返回并且线程的消息泵准备好接收消息之前阻塞主线程的最佳方法是什么?
答案 0 :(得分:4)
您真的不需要等待消息泵。您只需要等待创建消息队列。这样,消息泵将在最终启动时接收所有发布的消息。这是我认为你可以做到的一种方式(省略错误检查):
CEvent myEvent;
CWinThread * myThread = AfxBeginThread( ..., CREATE_SUSPENDED );
QueueUserAPC( MyCallback, *myThread, reintepret_cast<ULONG_PTR>( &myEvent ) );
myThread->Resume();
WaitForSingleObject( myEvent, INFINITE );
在Windows中,一旦线程启动,它就会在调用其入口点之前运行任何排队的用户APC。因此,这可以让您在MFC框架接管之前在新线程上隐藏一些代码。你的APC回调看起来像这样:
VOID CALLBACK MyCallback( ULONG_PTR param )
{
// Call peek message to force the creation of the thread's message queue.
MSG dummy;
PeekMessage( &dummy, NULL, 0, 0, PM_NOREMOVE );
CEvent * pEvent = reinterpret_cast<CEvent *>( param );
pEvent->SetEvent();
}
答案 1 :(得分:1)
彼得的答案很好,他认识到“你只需要等待创建消息队列”。这一启示导致以下链接显示在相关答案中:WaitForSingleObject returns wait failed due to invalid handle,这表明了一种更简单的方法来做彼得所建议的。