C# 当系统处于休眠状态时,windows服务中的计时器如何工作?

C# 当系统处于休眠状态时,windows服务中的计时器如何工作?,c#,timer,windows-services,C#,Timer,Windows Services,假设我有一个windows服务,它的计时器设置为每6小时运行一次,我希望它一天启动4次。比如说:0000,0600,12001800。(军事时间,同00:00等) 如果系统在1000时进入睡眠状态,在1700时醒来,会发生什么情况 它会在1900时再次开火吗,因为它的计时器有2个小时 它是否会立即开火(因为它错过了1200的约会),然后在2300再次开火(将当前时间加上6小时?) 我注意到,当计算机进入睡眠状态时,它不会启动OnPause或OnContinue方法 如果有人能了解上述情况下系统的

假设我有一个windows服务,它的计时器设置为每6小时运行一次,我希望它一天启动4次。比如说:0000060012001800。(军事时间,同00:00等)

如果系统在1000时进入睡眠状态,在1700时醒来,会发生什么情况

  • 它会在1900时再次开火吗,因为它的计时器有2个小时
  • 它是否会立即开火(因为它错过了1200的约会),然后在2300再次开火(将当前时间加上6小时?)
  • 我注意到,当计算机进入睡眠状态时,它不会启动
    OnPause
    OnContinue
    方法

    如果有人能了解上述情况下系统的行为,那就太好了。

    干杯,提前感谢。

    正如评论中已经提到的:使用任务计划程序而不是计时器。有关进一步讨论,请参阅

    不过,计时器在睡眠中的行为仍然是一个有趣的问题。在您提到的具体案例中,选择2。将是观察到的行为。计时器将在恢复时启动,因为它在睡眠期间错过了一个事件,随后再次从0开始计数,因此下次启动将在23:00。具有支持观察的示例代码


    如果要检测系统何时休眠和恢复,请订阅该事件。此事件包含一个
    模式
    ,其中您感兴趣的是
    挂起
    恢复
    出于我的需要,我使用了一个windows服务,它将检查是否以及何时需要执行下一个操作,并简单地将计时器设置为该时间。
    windows服务将在从睡眠恢复时更新该时间

    好处是:

    • 不受睡眠/唤醒时间的影响
    • 计划程序未运行任何控制台应用程序
    • 使用(快速)和(如何在NLog教程中使用咆哮)在桌面上接收通知
    • 在系统上也有一个日志
    因为我的情况很简单,功能已经在一个单独的dll中了,所以我对稳定性和内存泄漏没有任何问题(如果我这样做了,我会感到羞耻)。这使我需要的事情每天发生一次,或者每次计算机醒来时发生一次,并且不会对系统造成额外的开销


    像Henrik一样,正确答案是2号

    我在linqpad中写了以下内容,与上面答案中的链接类似:

    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 :");
    }
    
    静态整数计数器=0;
    静态System.Timers.Timer my_Timer;
    void Main()
    {
    //设置计时器,每分钟触发一次。
    my_timer=new System.Timers.timer();
    DateTime now=DateTime.now;
    my_timer.Interval=(60-now.Second)*1000;//在分钟开始时开火
    Format(“在{0}秒内的第一个滴答声”,my_timer.Interval/1000).Dump();
    my_timer.appeated+=OnTimer;
    我的计时器。开始();
    而(计数器<5){//一直睡到5点
    睡眠(5000);
    }
    //停下来说再见
    我的计时器。停止();
    DateTime.Now.Dump(“已完成运行,正在关闭”);
    }
    //打印时间并计数每个计时器的滴答声
    void OnTimer(对象发送方,System.Timers.ElapsedEventArgs args)
    {
    if(my_timer.Interval!=60000)//设置为第一次后一分钟
    my_timer.Interval=60000;
    DateTime.Now.ToString(“HH:mm:ss.fff”).Dump(“启动计时器时:”;
    (计数器++).Dump(“静态计数器:”);
    }
    
    获得结果:

    第一次滴答声:37秒

    启动计时器:08:47:00.552
    静态计数器:0

    启动计时器:08:48:00.557
    静态计数器:1

    启动计时器:08:49:00.571
    静态计数器:2

    //在08:49:30关闭计算机3分钟

    启动计时器:08:52:33.509
    静态计数器:3

    启动计时器:08:53:33.510
    静态计数器:4

    已完成运行,正在关闭 2014年9月1日上午8:53:38

    所以,很明显,计算机知道它漏掉了一个滴答声,它触发了该方法一次,然后从那里继续。请注意,它只触发一次


    但是如果有人知道幕后发生了什么,他会很高兴的。你为什么不使用任务调度器呢?睡眠听起来更像是一个电源事件。因此,您应该重写
    ServiceBase.OnPowerEvent
    ,并将
    CanHandlePowerEvent
    设置为true。不过,不确定计时器会发生什么。你应该能够很容易地测试它。我的猜测是,当你从睡眠中恢复时,你需要重新调整它们。@ZippyV我知道调度程序与Win.Ser+计时器,但我正在玩Win.Ser.,不知道是否有人知道,因为我找不到任何东西around@MarcelN. 是的,在搜索时,我发现了
    OnPowerEvent
    ,但它似乎更专注于笔记本电脑,因为它有
    电池电量低
    等功能。我发现的另一件事是:查看中的最后一篇帖子。