系统Windows 2008 R2安装程序Windows 2008用户控件系统管理员线程Windows VistaWindows 7设计 / 图形所有主题架构师高级C# 4.0中级开发Windows.NETC#
用于 .NET 应用程序的任务调度程序库
这是“用于 .NET 应用程序的任务调度程序库”的替代方案
引言
这是一个简单的类,可用于安排每天在特定时间运行任务,或每隔一段时间运行任务。 这可用于任何计划任务,例如清理文件或任何其他资源、将数据从任何外部数据提供程序同步到您的应用程序、定期优化数据库、发送批量电子邮件或其他通知(例如在带宽使用较少的时间(可能在夜间)发送 SMS)等。
背景
我在解决方案中使用 .NET framework >=4.0 类 Task。 因此,请检查您的项目是否与此实用程序兼容。 这是一个尝试,旨在为“用于 .NET 应用程序的任务调度程序库”创建一个替代方案,并通过将 Scheduler
类拆分为两个类来获得更简洁的设计,正如 John Brett 在 此评论中建议的那样。
Using the Code
在此设计中,有一个 abstract
泛型类 ServiceBase
。 我更喜欢使用 abstract
类而不是 interface
来实现代码重用。
// Used to schedule tasks to run on regular intervals or on specific time of everyday.
public abstract class SchedulerBase<T> : Timer, IDisposable
{
// Returns a new instance of timer and starts it
// param name="Time": Interval time to execute the timer
// param name="Trigger": Action to call in a new Thread when timer elapses
protected SchedulerBase(TimeSpan Time, Action Trigger)
{
this.Time = Time;
Reset();
Elapsed += (s, e) => Task.Factory.StartNew(Trigger);
}
// Returns a new instance of timer and starts it
// param name="Time": Interval time to execute the timer
// param name="Trigger": Function to call in a new Thread when timer elapses
// param name="CallBackFn": Optional call back Action to execute after completing the Trigger function.
// Input parameter of this Action is the result of Trigger function
protected SchedulerBase(TimeSpan Time, Func<T> Trigger, Action<T> CallBackFn)
{
this.Time = Time;
Reset();
Elapsed += (s, e) => Task.Factory.StartNew(Trigger)
.ContinueWith(prevTask => CallBackFn(prevTask.Result));
}
protected TimeSpan Time { get; set; }
// Resets and restarts the scheduler
public void Reset()
{
Stop();
Interval = GetInterval();
Enabled = true;
Start();
}
// A template method to return TimeSpan difference of the next schedule time with respect to current time
protected abstract double GetInterval();
// Stop and dispose the timer
protected override void Dispose(bool disposing)
{
Stop();
base.Dispose(disposing);
}
}
IntervalScheduler
是继承自 SchedulerBase
类的具体类之一。 此类提供基于间隔的调度行为。
// Scheduler which triggers at a specific time interval
public class IntervalScheduler<T> : SchedulerBase<T>
{
public IntervalScheduler(TimeSpan Time, Action Trigger) : base(Time, Trigger) { }
public IntervalScheduler(TimeSpan Time, Func<T>
Trigger, Action<T> CallBackFn) : base(Time, Trigger, CallBackFn) { }
protected override double GetInterval()
{
return Time.TotalMilliseconds;
}
}
TimeScheduler
是另一个继承自 SchedulerBase
的类,它提供在一天中的特定时间运行调度程序的行为。
// Scheduler which runs at a specific time everyday.
public class TimeScheduler<T> : SchedulerBase<T>
{
public TimeScheduler(TimeSpan Time, Action Trigger) : base(Time, Trigger) { }
public TimeScheduler(TimeSpan Time, Func<T> Trigger,
Action<T> CallBackFn) : base(Time, Trigger, CallBackFn) { }
protected override double GetInterval()
{
// Scheduled time of today
DateTime nextRunOn =
DateTime.Today.AddHours(Time.Hours).AddMinutes(Time.Minutes).AddSeconds(Time.Seconds);
if (nextRunOn < DateTime.Now)
{
nextRunOn = nextRunOn.AddMinutes(1);
}
if (nextRunOn < DateTime.Now) // If nextRunOn time is already past, set to next day
{
nextRunOn = nextRunOn.AddDays(1);
}
return (nextRunOn - DateTime.Now).TotalMilliseconds;
}
}
您可以通过简单地调用特定的构造函数来创建调度程序。
// A function that executes every 5 minutes
SchedulerBase<dynamic> FiveMinScheduler =
new IntervalScheduler<dynamic>(TimeSpan.FromMinutes(5), FiveMinScheduledFn);
// A function that executes only once in a day at a specific time
SchedulerBase<dynamic> NightScheduler =
new TimeScheduler<dynamic>(TimeSpan.FromHours(2), NightScheduledFn);
// Using parameters in a schedule function
SchedulerBase<dynamic> ParamerizedScheduler =
new IntervalScheduler<dynamic>(TimeSpan.FromDays(7), () => ParamerizedScheduledFn(i, 6));
// Using result of scheduled function in another callback function
SchedulerBase<string> CallbackScheduler =
new IntervalScheduler<string>(TimeSpan.FromSeconds(30),
() => ParamerizedScheduledFn(i, 6), CallBackFunc);
上面使用的一些计划函数是
internal void NightScheduledFn()
{
Helper.WriteLog("I run at 2AM everyday. Current time is: " + DateTime.Now);
}
internal string ParamerizedScheduledFn(int i, int j)
{
Helper.WriteLog(String.Format("Got parameters i={0}
and j={1}. Current time is: {2}", i, j, DateTime.Now));
return (i*j).ToString(CultureInfo.InvariantCulture);
}
internal void CallBackFunc(string result)
{
Helper.WriteLog(String.Format("Scheduled task finished on: {0}.
Result of scheduled task is: {1}", DateTime.Now, result));
}
关注点
通过比较替代实现,我们可以看到将 Scheduler
类拆分为两个类如何实现更简洁的设计。