可等待计时器包装类






4.81/5 (9投票s)
Windows WaitableTimer 的 C# 包装类。
引言
这个类是 Windows 可等待计时器的包装。它与 System.Timers.Timer
非常相似,但有两个重要的区别:它可以唤醒处于挂起状态(睡眠或休眠)的计算机,并且它支持更大的间隔值。
背景
我一直在编写一个类来复制 Windows 任务计划器的功能,以便可以以编程方式管理诸如“每年三月、六月和九月的最后一个星期四下午 6 点,每十分钟持续一小时”之类的循环事件。经过一些研究,我发现标准的 System.Timers.Timer
(以及底层的 System.Threading.Timer
)不太适合这项工作,因为间隔限制为 0xffffffff 毫秒(大约 50 天),如图所示
System.Timers.Timer tmr = new System.Timers.Timer();
tmr.Interval = double.MaxValue;
tmr.Start(); //System.ArgumentOutOfRangeException here at runtime
此外,也无法从节能模式恢复以执行任务,这对我来说至关重要,因此我开始寻找任何可用的替代方案。WaitableTimer
包装类为您提供了这种替代方案。尽情享受吧!
使用代码
如您所见,WaitableTimer
类在属性、方法和事件方面与 System.Timers.Timer
非常相似。不应有任何学习曲线,并且唯一引入的新属性是 ResumeSuspended
。当 true
时,此属性告诉计时器它应该唤醒计算机以运行 Elapsed
事件处理程序
using tevton.Win32Imports;
//....
WaitableTimer timer = new WaitableTimer();
timer.ResumeSuspended = true;
timer.Elapsed +=
new WaitableTimer.ElapsedEventHandler(timer_Elapsed);
timer.Interval = 60000;
timer.Start();
如您所见,我不得不重新创建 ElapsedEventHandler
/ElapsedEventArgs
,因为 System.Timers.Timer
的没有公共构造函数。随附的演示项目将模拟启动计时器后的 Sleep
(并且通过一个简单的更改,Hibernate
)模式,因此您将看到它实际运行。
注释
由于 Sleep
/Hibernate
模式的性质,计时器不会非常准确,因为机器必须完全唤醒才能运行任务,这需要一些时间。您还应该记住,如果您的启动列表中首先有不同的操作系统(例如我机器上的默认 Ubuntu),则从休眠恢复可能会意外加载该操作系统。
演示项目是用 C# 2008 编写的,无法在旧版本中正确编译,但类不应依赖于 C# 版本。
参考文献
演示项目中的 Sleep
模式是通过 KPD 团队的 WindowsController
类 实现的。XML 注释是从 System.Timers
命名空间窃取的。WaitableTimer
由 MSDN 记录。
历史
- 2008 年 11 月 - 初始发布。