2011-06-22 93 views
1

我打電話給AfxBeginThread並使用CWinThread在我的MFC應用程序中創建一個UI線程。我注意到如果我的主線程在CWinThread :: InitInstance()函數返回之前試圖將PostThreadMessage()傳遞給我的新線程,那麼PostThreadMessage()將返回錯誤:無效的線程句柄。等待AfxBeginThread/CWinThread消息泵處於活動狀態?

我的猜測是,直到InitInstance返回後,新線程上的消息泵纔會設置。我見過的關於AfxBeginThread的示例代碼和我讀過的文檔沒有很好地解釋這種行爲,或者顯示了一個模式來等待線程被初始化。

在InitInstance返回並且線程的消息泵準備好接收消息之前阻塞我的主線程的最好方法是什麼?

回答

1

彼得的回答是,他認識到,「你只需要等待要創建的消息隊列」好。這個啓示導致下面的鏈接出現在相關的答案中:WaitForSingleObject returns wait failed due to invalid handle,這表明了一種更簡單的方式來做彼得建議。

+0

你說得對,我的回答太複雜了。在回答之前,我應該多研究一下CWinThread類。關鍵點是在發信號通知事件之前在新線程上調用PeekMessage()。 InitInstance,OnIdle和Run都是可行的。 –

3

你並不需要等待消息泵。你只需要等待消息隊列的創建。這樣,消息泵在終於啓動時將收到所有發佈的消息。這裏有一個方式,我認爲你可以做到這一點(檢查省略錯誤):

CEvent myEvent; 

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

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

myThread->Resume(); 

WaitForSingleObject(myEvent, INFINITE); 

在Windows中,只要一個線程啓動時,它運行調用它的入口點之前任何排隊的用戶裝甲運兵車。所以這可以讓你在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(); 
} 
+0

yikes。我明天會試試這個。 – Erik

相關問題