For implementation of my Windows service, I need to be able to set a timer for a certain duration of system being in the working state. So I originally came up with the following code.
A) Setting up a waitable timer (error checks are omitted):
HANDLE hWTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
//As an example, set timer to wait for 40 minutes
int nWaitMins = 40;
LARGE_INTEGER li;
ULONGLONG uiWaitMs = (ULONGLONG)nWaitMins * 60LL * 1000LL;
li.QuadPart = -10000LL * uiWaitMs; //Convert to 100 nanosecond intervals (must be negative for relative time)
::SetWaitableTimer(hWTimer, &li, 0, NULL, NULL, FALSE); //Don't wake the system
B) Waiting for it (from a worker thread):
//Wait for timer to fire
::WaitForSingleObject(hWTimer, INFINITE);
This works really well with one caveat (if the system is not put into sleep mode or hibernated.) In that case what happens is best illustrated in this diagram:
when what I need it to do is this:
Is there a timer to do what I want here?
PS. Copies of my service submit reports to our web server from multiple workstations. With my technique above I try to randomize submission times to alleviate server workload. Since all workstations are put into sleep and then woken up roughly at the same time, my "randomization" technique doesn't work when machines wake up from sleep.
PS2. I need to point out that I need this to work under Windows XP.