基于事件的调度程序






2.71/5 (6投票s)
基于计时器控件的周期性调度器
引言
本文旨在解决应用程序中的调度问题。
我们都知道一个简单的场景,我们需要编写一些需要在每 X 时间运行的代码。在这种情况下,解决方案很简单——Timer。你提供迭代时间(比如 5 分钟),设置事件处理程序,以便每 5 分钟触发一次,就完成了。
当要求你从 Y 开始每 X 时间运行应用程序时,情况会变得更复杂。在这种情况下,你需要有人/某物知道何时开始(通常在现在不到 X 时间内),然后跟踪迭代。
背景
我需要这个解决方案的原因是需要运行一个 Windows 服务,该服务将在每天 03:00 执行一些数据库操作。这个新应用程序是为了取代一个 SQL Server 作业,后者基本上做同样的事情,只是这次我们需要在其他地方运行应用程序。
Using the Code
使用非常简单,并且与我们通常使用 Timer
控件的方式非常相似
DateTime start = System.DateTime.Now.AddMinutes(1);
Scheduler.PeriodicSchedules scheduler =
new Scheduler.PeriodicSchedules
(start,Scheduler.PeriodicSchedules.ExecutionType.Minutely);
scheduler.Elapsed+=new System.Timers.ElapsedEventHandler(scheduler_Elapsed);
scheduler.Enabled = true;
如你所见,PeriodicSchedules
构造函数接收一个 DateTime
对象,表示它应该第一次运行的时间,以及一个 ExecutionType
枚举器,表示间隔。
可以轻松地将枚举器扩展到你可能需要的任何间隔。
关注点
我使用了 ICurrentTime 接口
以便为应用程序启用单元测试。这样,我可以从外部注入机器的 CurrentTime
,而不是为了测试不同的场景而玩弄本地时钟
public interface ICurrentTime
{
DateTime GetCurrentDateTime();
}
以及在测试时
public class CurrentTime:ICurrentTime
{
DateTime currentTime;
public CurrentTime(DateTime mynow)
{
currentTime = mynow;
}
public DateTime GetCurrentDateTime()
{
return currentTime;
}
}
[Test]
public void OneHourEarlierInterval()
{
CurrentTime now = new CurrentTime(new DateTime(2007, 5, 30, 15, 0, 0));
Scheduler.PeriodicSchedules scheduler =
new Scheduler.PeriodicSchedules(14, 0, 0,
Scheduler.PeriodicSchedules.ExecutionType.Hourly, now);
Console.WriteLine(scheduler.Interval.ToString());
Assert.AreEqual((double)(60000 * 60), scheduler.Interval);
}
历史
- 2007 年 6 月 2 日:初始发布