Windows 服务中具有不同间隔时间的多个计时器
Multiple timers with different interval times in Windows Service
我的服务会运行 多次执行日常任务。这是我的服务代码:
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/. I have no knowledge of this wrapper, I found it referenced in this question: C# API for Task Scheduler 2.0.
找到 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 事件以便我可以传递相应的参数。任何更好的解决方案将不胜感激!
使用单个 System.Threading.Timer
以某个最低分辨率定期过期(比如每 60 秒),您可能会获得更好的结果。
当您的服务启动时,计算您所有任务的下一个预定运行时间,并在执行过程中将它们插入优先级队列。优先队列应该按预定的运行时间排序。
每次您的计时器到期时,评估队列头部任务的预定 运行 时间。如果任务的 运行 时间已到,将其从队列中弹出并将其推入队列,您的工作线程将在其中执行该任务。重复此过程,直到您 运行 队列中的任务结束或找到尚未准备好 运行 的任务。
任务完成后,计算下一个预定的 运行 时间并将其插入预定的优先级队列。
如果您的服务纯粹是为了 运行 执行这些计划任务,我建议您考虑改用 Windows 任务计划程序。老实说,即使您的服务提供了其他功能,使用 Windows 任务计划程序来执行 运行 定期任务仍然是比尝试推出自己的计划程序更好的选择。
您可以在此处 http://taskscheduler.codeplex.com/. I have no knowledge of this wrapper, I found it referenced in this question: C# API for Task Scheduler 2.0.
找到 Windows 任务计划程序的托管包装器