Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?
like image 518
Basj Avatar asked Jan 29 '23 20:01

Basj


1 Answers

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

like image 160
Mike Nakis Avatar answered Feb 01 '23 11:02

Mike Nakis