views:

39

answers:

2

Hi,

I have a timer class which uses CreateTimerQueueTimer and DeleteTimerQueueTimer. I receive callbacks to the class objects as expected. How do i make sure the timer does not fire when the app is busy drawing the UI or doing some intensive renders etc ?? I am not concerned about high resolution, just that it has to fire when app is idle.

i am using the following to create the timer.

BOOL timerCreated = ::CreateTimerQueueTimer(&mTimerRef,
                                            NULL,
                                            TimerCallback,
                                            (PVOID)(this),
                                            inFireDelay * 1000,
                                            inInterval * 1000,
                                            WT_EXECUTEINUITHREAD);
// using timer queues because i dont have access to a hWnd in this class.

Sorry i cannot use MFC/.NET stictly win32 only.

Thanks, Abhinay.

+2  A: 

That's in general not possible. The callback is made on a threadpool thread, you cannot wave a magic flag and ask "don't fire please". Even if it were possible, that's an inevitable race condition, the thread might have already been started but didn't get a chance to execute yet.

All you can do is block the thread, use a critical section or a mutex in your callback. Acquiring the mutex when your UI thread is 'not idle' is pretty unpractical, you'd have to do so in your message loop. In general, you only want to protect shared state, variables that are both accessed in your UI thread and your callback.

If you are contemplating this because you don't want the callback to consume CPU cycles while your UI thread is busy then keep in mind that almost any machine nowadays has at least two CPU cores. That problem doesn't need to be fixed.

Hans Passant
Thanks, I wanted to make sure my callback function did not affect the UI response.
Abhinay K Reddyreddy
A: 

WRT: // using timer queues because i dont have access to a hWnd in this class.

You do not need to pass an hWnd to SetTimer - you can just register a timer proc that is called back. WM_TIMER messages are low priority and are only generated by the message queue when there are no other messages pending so you automatically get the behavior you want.

If the timer messages are doing drawing, theres a lot of potential for contention over the device driver to serialize a thread pool anyway, but with multi core CPUs being the norm, doing timer processing in worker threads doesn't have to interfere with the UI thread at all.

Chris Becke