dennisV
dennisV

Reputation: 1119

Timer in a win32 service

Can someone please point me to the easiest way to have a timer in a Win32 service?

I suppose I could create a dummy window for this purpose or have a second thread do tick counts, but what's best? Is there a more elegant way?

Thanks in advance.

Upvotes: 9

Views: 11495

Answers (6)

David L Morris
David L Morris

Reputation: 1513

In one of your comments you said that "...the service is processing stuff in other threads, I just need to check the status of a few files every second."

Polling is not an optimal way of checking file status, and will adversely affect system performance. While there are (sometimes) problems doing this over networks, you should check out http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx or http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx for how to do it and http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx for why you should.

Upvotes: 1

Adam Mitz
Adam Mitz

Reputation: 6043

Instead of using UI timers (even though you can use the NULL window handle as shown by Mr. 1800-INFO) you can use kernel waitable timer objects. See CreateWaitableTimer in the API docs. These can then be waited-on using WaitForSingleObject or WaitForMultipleObjects, etc, which is especially useful if that's already how your service waits for external events.

If it's not clear from that first link, the SetWaitableTimer function can associate a completion routine (user callback) with the timer. Remember to use the ...Ex versions of WaitForMultipleObjects (etc.) so that the thread is in an "alertable" state.

Upvotes: 5

John Dyer
John Dyer

Reputation: 2368

Are you just trying to "wake up" every now and then to do some work? You can always use Sleep().

Additionally, I typically have a thread that is in a while(1 == 1) loop with a sleep inside. There I can check for the shutdown request and other misc housekeeping. You could use that system to tickle an event or mutex for the worker thread in the app.

Upvotes: 0

denis phillips
denis phillips

Reputation: 12780

You can use Timer Queues (http://msdn.microsoft.com/en-us/library/ms686796.aspx). They don't require an HWND.

Upvotes: 15

Steve
Steve

Reputation: 995

You can use SetTimer to set the timer, then catch the WM_TIMER message in your message loop.

Example:

// Set a timer to expire in 10 seconds

SetTimer(hwnd,IDT_TIMER1, 10000,(TIMERPROC) NULL);

... then in message loop:

switch (wParam)

{ 

    case IDT_TIMER1: 

        // Boom goes the dynamite

You can also decleare a function of type TIMERPROC and have that be called when the timer expires, if you don't want to do the message loop handling.

Upvotes: 1

1800 INFORMATION
1800 INFORMATION

Reputation: 135433

You can send your main thread WM_TIMER messages. The lParam for the message is the address of a callback function, or you can leave it NULL and handle it yourself in your message pump.

In this example, we are sending the timer to the thread message pump, there is no requirement to have a window associated with the timer.

UINT timer;

VOID CALLBACK Timer(HWND hwnd,
    UINT uMsg,
    UINT_PTR idEvent,
    DWORD dwTime
)
{
  KillTimer(0, timer);
}

timer=SetTimer(0, // window handle
    0, // id of the timer message, leave 0 in this case
    10000, // millis
    Timer // callback
  );

// pump messages
while (GetMessage) etc...

The Timer callback will be called by DispatchMessage. This question reminded me of the recent ONT.

Upvotes: 4

Related Questions