2009-07-06 34 views
1

我有一個在Windows Vista上運行的多線程仿真。當我使用PostThreadMessage在線程之間發送消息時,即使我非常確定(從調試器中逐步過來)線程ID是有效的,並且線程有消息隊列,我得到了ERROR_INVALID_THREAD_ID,因爲我從每個線程調用PeekMessage在我創建它們之後,按照MSDN中的規定。據我所知,目標線程可能暫停,但這應該不成問題。PostThreadMessage返回ERROR_INVALID_THREAD_ID

什麼嘗試的線索?我正在模擬一個基於RTOS的應用程序,所以我希望不必放入太多的Windows特定代碼。

編輯 -

另一條線索 - 如果刪除所有的信號量阻止,郵件正常工作(雖然有一些已知的競態條件)。但是消息隊列不應該受到線程阻塞的影響,對吧?

編輯2 該代碼還具有以下重試機制,如MSDN所建議的。但它仍然不起作用 - 重試總是失敗。嗯.....

BOOL bResult = false; 
int retry = 0; 
DWORD dwError = 0; 
do 
{ 
    bResult = PostThreadMessage(pTaskHandle->dwThreadID,0,0,(LPARAM)pMessage); 
    if (!bResult) 
    { 
     dwError = GetLastError(); 
     retry++; // should only happen once, if the dest thread has no msg queue 
        // the retry establishes the queue 
     Sleep(500); 
    } 
} while (!bResult && retry<3); // MSDN says try this a few times to start msg queue 

回答

0

你提到你打電話的PeekMessage創建線程之後,但做這些線程具有被分派的消息充分,積極的消息處理循環? msdn說:

調用PostThreadMessage。如果失敗,請調用睡眠函數並再次調用PostThreadMessage。重複直到PostThreadMessage成功。

這聽起來有點愚蠢,如果唯一的要求是線程調用PeekMessage一次。

另外請注意,通過發佈的消息。 PostThreadMessage不會派發到DispatchMessage中。這看起來很明顯,因爲沒有窗口可以顯示消息,但我已經看到人們這樣做了,特別是在使用MsgWaitForMultipleObjects等等來處理句柄時。在這種情況下,您似乎不太可能會收到ERROR_INVALID_THREAD_ID ......更有可能您錯過了該消息。

+0

謝謝 - 我應該提到,我已經在代碼中的睡眠重試功能。線程沒有與它們關聯的窗口對象,所以它們沒有傳統的消息處理循環 - 我使用MsgWaitForMultipleObjects,使用QS_ALLEVENTS掩碼,它在PostThreadMessage之後返回。我想知道是否有錯誤的地方。我將檢查 – Jeff 2009-07-07 13:59:49