【问题标题】:Multiple timers with different interval times in Windows ServiceWindows 服务中具有不同间隔时间的多个计时器
【发布时间】:2015-07-19 03:33:44
【问题描述】:

我的服务将多次运行日常任务。这是我的服务代码:

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 事件,以便我可以传递相应的参数。任何更好的解决方案将不胜感激!

【问题讨论】:

    标签: c# timer windows-services


    【解决方案1】:

    使用单个System.Threading.Timer 可能会获得更好的结果,该System.Threading.Timer 会以某个最小分辨率定期到期,比如每 60 秒一次。

    当您的服务启动时,计算所有任务的下一个计划运行时间,并在执行过程中将它们插入优先级队列。优先级队列应按计划运行时间排序。

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

    一旦任务完成,计算它的下一个计划运行时间并将其插入计划的优先级队列中。

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

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

    【讨论】:

    • 你能给我一些工作的 Windows 任务计划程序代码示例吗?
    猜你喜欢
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 1970-01-01
    • 2021-01-09
    • 2012-01-29
    相关资源
    最近更新 更多