Search code examples
c++windowsmultithreadingwinapitimer

Does SetTimer (with callback function) work by starting a new thread?


When using SetTimer this way:

SetTimer(hWnd, IDT_TIMER_LONGPROCESSING, 2000, (TIMERPROC) NULL);
DoSomethingElse();

the execution continues immediately (i.e. it's non-blocking and DoSomethingElse() is executed immediately), but when this message arrives

case WM_TIMER:
    if (wParam == IDT_TIMER_LONGPROCESSING)
         DoAOneSecondLongJob();

then it blocks the "window message loop" again during the 1-second long processing, resulting in a unresponsive interface. That's normal behaviour with SetTimer just posting a timer message.

But I see SetTimer can also be used in a second way, with a callback function:

VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{ 
    DoAOneSecondLongJob();
}

// in another function    
SetTimer(hwnd, IDT_TIMER_LONGPROCESSING, 2000, (TIMERPROC) MyTimerProc);

Question:

  • Will this method be blocking as well?

or

  • Will it solve the unresponsive-interface-during-1-second problem? If so, how? Is there a new thread creation involved under the hood?

Solution

  • No, it does not use a separate thread, so yes, it will be blocking. It is just a convenience function which is making use of WM_TIMER internally. You should take a hint from the fact that it still involves a hwnd in its workings.

    If you want something to run on a different thread, you need to start a different thread.

    MSDN says:

    When you specify a TimerProc callback function, the default window procedure calls the callback function when it processes WM_TIMER. Therefore, you need to dispatch messages in the calling thread, even when you use TimerProc instead of processing WM_TIMER.

    See MSDN - SetTimer function