假设我有一个Windows服务,它有一个设置为每6小时运行一次的计时器,我希望它每天发射4次。让我们说: 0000 , 0600 , 1200 1800 。 (军事时间,与00:00等相同......)
如果系统以 1000 进入睡眠状态,并且在 1700 时醒来,会发生什么?
我注意到,当计算机进入睡眠状态时,它不会触发OnPause
或OnContinue
方法。
如果有人能够在上述案例中阐明系统的行为,那就很有用了。
干杯,并提前感谢。
答案 0 :(得分:2)
正如评论中已经提到的:使用任务计划程序而不是计时器。有关进一步的讨论,请参阅this article。
但是,计时器在睡眠期间的表现仍然很有趣。在您提到的特定情况下,选项2将是观察到的行为。计时器将在恢复时触发,因为它在睡眠期间错过了一个事件,然后再次从0开始计数。下一次点火将在23:00进行。 This answer有示例代码来支持观察。
如果您想要检测系统何时休眠和恢复,请订阅SystemEvents.PowerModeChanged
事件。此活动的PowerModeChangedEventArgs
包含Mode
,您感兴趣的是Suspend
和Resume
。
答案 1 :(得分:0)
根据我的需要,我最终选择了一项Windows服务,该服务将检查是否以及何时需要进行下一次操作,并将计时器设置为该时间。
Windows服务将在从睡眠状态恢复时更新该时间。
好处是:
由于我的案例很简单,所以功能已经在一个单独的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 :");
}
获得结果:
首先登入:37秒
On Timer被解雇:08:47:00.552
静态计数器:0On Timer被解雇:08:48:00.557
静态计数器:1On Timer被解雇:08:49:00.571
静态计数器:2//在08:49:30关闭电脑3分钟
On Timer被解雇:08:52:33.509
静态计数器:3On Timer被解雇:08:53:33.510
静态计数器:4完成跑步,关闭 1/09/2014 8:53:38 AM
所以,显然计算机知道它错过了一个滴答声,它会触发该方法一次,并从那里继续。请注意,它只会触发一次。
如果有人知道幕后发生的事情可以为此提供更多信息,那将会很高兴。