2012-09-24 33 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

只要有一个处理消息的入口点,一次只能处理一个消息。你可以通过在已经运行的事件处理程序中处理更多的消息来解决问题,但是不要这样做,你应该没问题。

相关问题