Windows Service中具有不同间隔时间的多个计时器
本文关键字:时间 计时器 Service Windows | 更新日期: 2023-09-27 18:03:20
我的服务将多次运行日常任务。这是我的服务代码:
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事件,以便我可以传递各自的参数。任何更好的解决方案将不胜感激!
您可能会有更好的结果使用单个System.Threading.Timer
定期到期在一些最小的分辨率,说每60秒。
当服务启动时,计算所有任务的下一个计划运行时间,并将它们插入到优先级队列中。优先级队列应按计划运行时排序。
每次计时器到期时,评估队列头部任务的计划运行时间。如果任务的运行时间已经到达,将它从队列中弹出,并将其推送到队列中,在那里它将由工作线程执行。重复此过程,直到队列中的任务用完或找到尚未准备好运行的任务为止。
任务完成后,计算它的下一个计划运行时间,并将其插入计划优先级队列。
如果你的服务纯粹是为了运行这些计划任务,我建议你考虑使用Windows任务调度程序。老实说,即使你的服务提供了其他功能,使用Windows任务调度程序来运行周期性任务仍然是一个比尝试运行你自己的调度程序更好的选择。
您可以在这里http://taskscheduler.codeplex.com/找到Windows任务调度程序的托管包装器。我不知道这个包装器,我发现它在这个问题中引用:c# API for Task Scheduler 2.0。