我想要一种能够安排回调的方法,我希望能够在不同的时间向“调度程序”对象注册许多不同的回调。这样的事情。
public class Foo
{
public void Bar()
{
Scheduler s = new Scheduler();
s.Schedule(() => Debug.WriteLine("Hello in an hour!"), DateTime.Now.AddHours(1));
s.Schedule(() => Debug.WriteLine("Hello a week later!"), DateTime.Now.AddDays(7));
}
}
我能够实现调度程序的最佳方法是让一个计时器在给定的时间间隔内运行,每次间隔时间过去我检查已注册的回调并查看是否有时间调用它们,如果是的话做。这很简单,但缺点是你只能获得计时器的“分辨率”。假设计时器设置为每秒一次,你注册一个回调,在半秒内被调用,它仍然可能不会被调用一整秒。
有没有更好的方法来解决这个问题?
答案 0 :(得分:2)
这是一个很好的方法。您应该动态设置计时器,以便在下一个事件发生时立即关闭。您可以通过将作业放入优先级队列来完成此操作。毕竟,在任何情况下,总是限于系统可以提供的分辨率,但您应编码以使其成为唯一限制因素。
答案 1 :(得分:1)
这样做的一个好方法是改变计时器的持续时间:告诉它在你的第一个/下一个预定活动到期时(但不是之前)关闭。
<
关于Windows不是实时操作系统的标准免责声明,因此其定时器必须始终有点不准确 >
答案 2 :(得分:1)
当列表中最早的项目到期时,您只需要调度程序唤醒并执行某些操作。之后,将计时器设置为下次唤醒调度程序。
添加新项目时,您只需将其计划与正在等待的当前计划进行比较。如果它早些时候取消当前计时器并将新项目设置为下一个计划项目。
答案 3 :(得分:0)
这是我写的一个类,使用.NET的内置Timer类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Sample
{
/// <summary>
/// Use to run a cron job on a timer
/// </summary>
public class CronJob
{
private VoidHandler cronJobDelegate;
private DateTime? start;
private TimeSpan startTimeSpan;
private TimeSpan Interval { get; set; }
private Timer timer;
/// <summary>
/// Constructor for a cron job
/// </summary>
/// <param name="cronJobDelegate">The delegate that will perform the task</param>
/// <param name="start">When the cron job will start. If null, defaults to now</param>
/// <param name="interval">How long between each execution of the task</param>
public CronJob(VoidHandler cronJobDelegate, DateTime? start, TimeSpan interval)
{
if (cronJobDelegate == null)
{
throw new ArgumentNullException("Cron job delegate cannot be null");
}
this.cronJobDelegate = cronJobDelegate;
this.Interval = interval;
this.start = start;
this.startTimeSpan = DateTime.Now.Subtract(this.start ?? DateTime.Now);
this.timer = new Timer(TimerElapsed, this, Timeout.Infinite, Timeout.Infinite);
}
/// <summary>
/// Start the cron job
/// </summary>
public void Start()
{
this.timer.Change(this.startTimeSpan, this.Interval);
}
/// <summary>
/// Stop the cron job
/// </summary>
public void Stop()
{
this.timer.Change(Timeout.Infinite, Timeout.Infinite);
}
protected static void TimerElapsed(object state)
{
CronJob cronJob = (CronJob) state;
cronJob.cronJobDelegate.Invoke();
}
}
}
答案 4 :(得分:0)
Quartz.Net作业调度程序。但是,这会调度类而不是委托。