65.9K
CodeProject 正在变化。 阅读更多。
Home

可等待计时器包装类

2008年11月17日

CPOL

2分钟阅读

viewsIcon

34042

downloadIcon

505

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 月 - 初始发布。
© . All rights reserved.