开发者

Wait for AfxBeginThread/CWinThread message pump to be active?

开发者 https://www.devze.com 2023-03-15 05:25 出处:网络
I\'m calling AfxBeginThread and using CWinThread to spin up a UI thread in my MFC app. I\'ve noticed that if my main thread tries to PostThreadMessage() to my new thread before the CWinThread::InitIn

I'm calling AfxBeginThread and using CWinThread to spin up a UI thread in my MFC app.

I've noticed that if my main thread tries to PostThreadMessage() to my new thread before the CWinThread::InitInstance() function returns, then PostThreadMessage() will return the error: invalid thread handle.

My guess is that the message pump on the new thread isn't setup until after InitInstance returns. The开发者_C百科 example code I've seen for AfxBeginThread and the documentation I've read don't do a good job of explaining this behavior, or show a pattern to wait for the thread to be initialized.

What's the best way of blocking my main thread until InitInstance has returned and the thread's message pump is ready to receive messages?


You don't really need to wait for the message pump. You just need to wait for the message queue to be created. That way, the message pump will receive all posted messages when it finally starts. Here's a way I think you could do it (error checking omitted):

CEvent myEvent;

CWinThread * myThread = AfxBeginThread( ..., CREATE_SUSPENDED );

QueueUserAPC( MyCallback, *myThread, reintepret_cast<ULONG_PTR>( &myEvent ) );

myThread->Resume();

WaitForSingleObject( myEvent, INFINITE );

In windows, as soon as a thread starts, it runs any queued user APCs before calling its entry point. So this lets you sneak in some code on the new thread before the MFC framework takes over. Your APC callback would look something like this:

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();
}


Peter's answer is good in that he recognized that "you just need to wait for the message queue to be created". That revelation caused the following link to show up in the related answers: WaitForSingleObject returns wait failed due to invalid handle, which demonstrates an easier way to do what Peter suggests.

0

精彩评论

暂无评论...
验证码 换一张
取 消