为调度程序选择合适的计时器

本文关键字:计时器 调度程序 选择 | 更新日期: 2023-09-27 18:28:43

我正在制作自己的调度器,它将用于我的一个WPF应用程序。

这是代码。

// Interface for a scheduled task.
public interface IScheduledTask
{
    // Name of a task.
    string Name { get; }
    // Indicates whether should be task executed or not.
    bool ShouldBeExecuted { get; }
    // Executes task.
    void Execute();
    }
// Template for a scheduled task.
public abstract class PeriodicScheduledTask : IScheduledTask
{
    // Name of a task.
    public string Name { get; private set; }
    // Next task's execute-time.
    private DateTime NextRunDate { get; set; }
    // How often execute?
    private TimeSpan Interval { get; set; }
    // Indicates whether task should be executed or not. Read-only property.
    public bool ShouldBeExecuted 
    { 
        get 
        {
            return NextRunDate < DateTime.Now;
        }
    }
    public PeriodicScheduledTask(int periodInterval, string name)
    {
        Interval = TimeSpan.FromSeconds(periodInterval);
        NextRunDate = DateTime.Now + Interval;
        Name = name;
    }
    // Executes task.
    public void Execute()
    {
        NextRunDate = NextRunDate.AddMilliseconds(Interval.TotalMilliseconds);
        Task.Factory.StartNew(new Action(() => ExecuteInternal()));
    }
    // What should task do?
    protected abstract void ExecuteInternal();
}
// Schedules and executes tasks.
public class Scheduler
{
    // List of all scheduled tasks.
    private List<IScheduledTask> Tasks { get; set; }
    ... some Scheduler logic ...
}

现在,我需要为调度器选择正确的.net定时器。里面应该有订阅的事件tick/perated,它会遍历任务列表,检查是否应该执行某个任务,然后通过调用task.Execute()来执行它。

更多信息。我需要将计时器的间隔设置为1秒,因为我正在创建的一些任务需要每隔一秒、两秒或更长时间执行一次。

我需要在新线程上运行计时器来启用用户在表单上的操作吗?哪个计时器最适合此计划程序

为调度程序选择合适的计时器

我会使用System.Timers.Timer

基于服务器的Timer设计用于多线程环境。服务器计时器可以在线程之间移动到处理引发的Elapsed事件,结果比Windows计时器正在按时引发事件。

我认为您不应该在单独的线程上手动启动它。我从来没有让它从UI中窃取CPU时间,尽管我的开发主要是在Winforms中,而不是WPF中。

您应该使用DispatcherTimer,因为它被集成到创建它的同一线程(在您的情况下是UI线程)上的调度器队列中:

DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += new EventHandler(timer_Tick);
timer.Start();