1.引言
實際應用中,我們是定義一個作業,定時器然后定時去調用。前面章節都介紹的時間調度、事件過濾(EventFilter)、任務方法(MethodCall) 這些都是這個作業零部件,這就是這節要介紹的Job。
2.Job
Scheduled Timer的Job是由時間調度器、任務方法,事件過濾器等組成,共同來達到預期的目的,單個不行,好像一個團隊,主要代碼如下
/// <summary> /// 定時器作業 /// </summary> public class TimerJob { public IScheduledItem Schedule; //是否同步 public bool SyncronizedEvent = true; public IResultFilter Filter; public IMethodCall Method; //public IJobLog Log; public bool Enabled = true; private delegate void ExecuteHandler(object sender, DateTime EventTime, ExceptionEventHandler Error); private ExecuteHandler _ExecuteHandler; public TimerJob(IScheduledItem schedule, IMethodCall method) { Schedule = schedule; Method = method; _ExecuteHandler = new ExecuteHandler(ExecuteInternal); } public DateTime NextRunTime(DateTime time, bool includeStartTime) { if (!Enabled) return DateTime.MaxValue; return Schedule.NextRunTime(time, includeStartTime); } public void Execute(object sender, DateTime begin, DateTime end, ExceptionEventHandler error) { if (!Enabled) return; List<DateTime> eventList = new List<DateTime>(); Schedule.AddEventsInInterval(begin, end, eventList); if (Filter != null) Filter.FilterResultsInInterval(begin, end, eventList); foreach (DateTime eventTime in eventList) { if (SyncronizedEvent) _ExecuteHandler(sender, eventTime, error); else _ExecuteHandler.BeginInvoke(sender, eventTime, error, null, null); } } private void ExecuteInternal(object sender, DateTime eventTime, ExceptionEventHandler error) { try { TimerParameterSetter setter = new TimerParameterSetter(eventTime, sender); Method.Execute(setter); } catch (Exception ex) { if (error != null) try { error(this, new ExceptionEventArgs(eventTime, ex)); } catch { } } } }
TimerJob的大致工作流程是,首先初始化時間調度器、任務方法、事件過濾器,再在執行作業時,先獲取這個時間調度的時間集合,再進行事件過濾,再在有效的事件集合里循環執行任務方法。Scheduled Timer中一個定時器Timer不是只對應一個Job,而是一個Job集合中,Scheduled Timer的Job集合,代碼很簡單,對一個集合的操作,聲明如下:
/// <summary> /// 計時器作業管理組 /// </summary> public class TimerJobList { private List<TimerJob> _List; public TimerJobList() { _List = new List<TimerJob>(); } public void Add(TimerJob Event) { _List.Add(Event); } public void Clear() { _List.Clear(); } public DateTime NextRunTime(DateTime time) { DateTime next = DateTime.MaxValue; //從列表中,獲得最低的日期時間。 foreach (TimerJob Job in _List) { DateTime Proposed = Job.NextRunTime(time, true); next = (Proposed < next) ? Proposed : next; } return next; } public TimerJob[] Jobs { get { return _List.ToArray(); } } }
3.總結
作業比較簡單,就是把之前的章節進行組合,主要看Job執行方法Execute,這也是定時器Timer的Elapsed事件將要調用的方法。