简体   繁体   中英

How do timers in a windows service behave when the system is asleep?

Assuming I have a windows service which has a timer that is set to run every 6 hours, I would expect it to fire 4 times a day. Let's say : 0000 , 0600 , 1200 1800 . (Military time, same as 00:00, etc...)

If the system goes to sleep at 1000 , and wakes at 1700 , what happens?

  1. will it fire again at 1900 , because it has 2 hours on the timer?
  2. will it fire straight away (because it missed it's 1200 appointment), and then fire again at 2300 (adding it's 6 hours to the current time?)

I've noticed that when the computer goes to sleep, it doesn't fire the OnPause or OnContinue methods.

If anyone can shed some light on the behaviour of the system in the above cases, It'll be great know.
Cheers, and thanks in advance.

As has already been mentioned in the comments: Use the task scheduler instead of timers. See this article for further discussion.

The question of how timers behave during sleep is still interesting, though. In the specific case you mention, option 2. will be the observed behavior. The timer will fire on resume because it missed an event during sleep and subsequently start counting from 0 again The next time it fires will thus be at 23:00. This answer has sample code to support the observation.

In case you want to detect when the system sleeps and resumes, subscribe to the SystemEvents.PowerModeChanged event. This event's PowerModeChangedEventArgs contains a Mode , of which you are interested in Suspend and Resume .

For my needs, I ended up going with a windows service that will check if and when next operation needs to be carried, and simply set the timer to that time.
The windows service will update that time upon resuming from sleep.

The benefits are :

  • Unaffected by sleep/wake times
  • no console apps being run by a scheduler.
  • using NLog (quick tutorial here ) and Growl (how to use Growl with NLog tutorial here ) to receive notifications on the desktop
  • having a log on the system as well

Since my case is simple, having the functionality is already in a separate dll, I don't have any issues with stability or memory leaks (and if I do, shame on me). This keeps what I need happening once a day, or once every time the computer wakes up, and doesn't incur extra overhead on the system.


Like Henrik replied and linked, the correct answer is number 2.

I've wrote the following in linqpad, which is similar to the link in the above answer:

static int counter = 0;
static System.Timers.Timer my_timer;

void Main()
{
    // Set up a timer to trigger every minute.
    my_timer = new System.Timers.Timer();

    DateTime now = DateTime.Now;
    my_timer.Interval = (60 - now.Second) * 1000; // Fire at beginning of minute
    string.Format("First tick in {0} seconds", my_timer.Interval/1000).Dump();

    my_timer.Elapsed += OnTimer;
    my_timer.Start();

    while (counter < 5) {    // sleep away until 5 ticks happen
        Thread.Sleep(5000);
    }

    // stop timer and say goodbye
    my_timer.Stop();
    DateTime.Now.Dump("Finished running, shutting down");
}

// Print time and counter every timer tick
void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
    if (my_timer.Interval != 60000) // set to one minute after first time
        my_timer.Interval = 60000; 

    DateTime.Now.ToString("HH:mm:ss.fff").Dump("On Timer fired:");
    (counter++).Dump("Static counter :");
}

Getting the results:

First tick in: 37 seconds

On Timer fired : 08:47:00.552
Static counter : 0

On Timer fired : 08:48:00.557
Static counter : 1

On Timer fired : 08:49:00.571
Static counter : 2

// Shut computer down for 3 minutes at 08:49:30

On Timer fired : 08:52:33.509
Static counter : 3

On Timer fired : 08:53:33.510
Static counter : 4

Finished running, shutting down 1/09/2014 8:53:38 AM

So, obviously the computer knows it missed a tick, it fires the method once, and continues from there. Note that it only fires once.

But would be happy if someone who knows what happens behind the scenes can shed some more light on this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM