2012-09-24 68 views
0

我花了一些時間試圖研究一個明確的答案,並找不到可靠的來源。在先前調度的消息回調完成之前觸發消息時會發生什麼?

我的場景相當簡單。我有一個消息泵設置的線程正在處理來自定時器的循環事件。這裏是消息泵源:

// create timer that goes off every 500 ms 
UINT_PTR myTimerID = SetTimer(NULL, 0, 500, TimerCallback); 

// message structure 
MSG msg; 

// process and handle messages for this thread 
BOOL getMessageStatus; 
while((getMessageStatus = GetMessage(&msg, NULL, 0, 0)) != 0) 
{ 
    // failed get message 
    if(getMessageStatus == -1) 
    { 
     printf("GetMessage FAILED!\n"); 
    } 
    // process timer message 
    else if(msg.message == WM_TIMER) 
    { 
     // invoke callback 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 
} 

如果TimerCallback花費的時間超過500毫秒,計時器將再次觸發它的事件。由於回調函數是在與消息泵相同的線程上執行的,我假定在消息泵處理下一個計時器消息之前回調必須完成。

這是正確的嗎?

回答

2

SetTimer()是一個基於消息的計時器。當計時器過去時,它會在消息隊列中設置一個特殊標誌。當您爲新消息抽取隊列時,如果已設置該標誌並且其他更高優先級的消息未在隊列中等待,則會創建一條WM_TIMER消息。當您的代碼忙於調度生成的WM_TIMER消息時,定時器可能會在後臺流逝並再次設置標誌,並在下次爲消息抽取隊列時生成新的WM_TIMER消息。因此,在回調中直接或通過模態對話框注意泵送消息,因爲這可能會導致遞歸調用定時器回調,從而可能導致堆棧隨時間溢出。但是如果你的消息抽取只在你的主線程循環中,那麼你會沒事的。

1

只要有一個處理消息的入口點,一次只能處理一個消息。你可以通過在已經運行的事件處理程序中處理更多的消息來解決問題,但是不要這樣做,你應該沒問題。

相關問題