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

基于事件的调度程序

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (6投票s)

2007年6月2日

CPOL

1分钟阅读

viewsIcon

34381

downloadIcon

700

基于计时器控件的周期性调度器

引言

本文旨在解决应用程序中的调度问题。

我们都知道一个简单的场景,我们需要编写一些需要在每 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 日:初始发布
© . All rights reserved.