2015-07-19 49 views
1

我的服务将多次运行日常任务。这里是我的服务代码:Windows服务中具有不同间隔时间的多个定时器

private DateTime m_scheduleTime; 
private List<Task> m_tasksList; // Task includes id and time ("23:00") 

protected override void OnStart(string[] args) { 
    SetSchedule(); 
} 

private void SetSchedule() 
{ 
    Timer[] timers = new Timer[m_tasksList.Count]; 
    int iHours = 0; int iMinutes = 0; 
    for (int i = 0; i < timers.Length; i++) 
    { 
     iHours = Int16.Parse(m_tasksList[i].Time.Split(':')[0]); 
     iMinutes = Int16.Parse(m_tasksList[i].Time.Split(':')[1]); 
     m_scheduleTime = DateTime.Today.AddDays(1).AddHours(iHours).AddMinutes(iMinutes); 
     timers[i] = new Timer(); 
     timers[i].Enabled = true; 
     timers[i].Interval = m_scheduleTime.Subtract(DateTime.Now).TotalSeconds * 1000; 
     timers[i].Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed); 
    } 
} 

protected void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    DoWork(int taskId); 
} 

上面的代码没有经过测试,我从相关的代码示例构建它。所以我的问题是我不知道我是否在正确的轨道上,如果我是正确的,我不知道哪个计时器触发_Elapsed事件,以便我可以传递相应的参数。更好的解决方案,将不胜感激!

回答

2

你很可能已经使用单一System.Threading.Timer,在某些最小分辨率定期到期,更好的结果说成每60秒。

当您的服务开始时,计算您所有任务的计划运行时间的下一个,并随时将它们插入优先级队列。优先队列应该按计划的运行时间排序。

你的每一个计时器到期时,评估任务的预定运行时间在你的队列的头。如果已经达到任务的运行时间,请将其从队列中弹出并将其推送到工作线程将执行的队列中。重复此过程,直到您用完队列中的任务或找到尚未准备好运行的任务。

一旦任务完成,计算它的下一个计划的运行时间,并把它插入到预定的优先级队列。

如果您的服务纯粹是为了运行这些计划任务的目的,我建议你可以考虑使用Windows任务计划程序来代替。老实说,即使您的服务提供了其他功能,使用Windows任务计划程序运行定期任务仍然是比尝试推出自己的计划程序更好的选择。

你可以找到一个托管包装的Windows任务计划程序,在这里http://taskscheduler.codeplex.com/。我不知道这个包装,我发现它在这个问题中引用:C# API for Task Scheduler 2.0

+0

你可以给我一些工作的Windows任务计划代码示例? – user1728585

相关问题