1、雖然Quart.NET已然很強大,但是還是需要自己去實現一個簡單版本的迷你版任務調度。
原因如下:
1.業務多,任務多
2.程序員的水平參差不齊,尤其是在沒有好的項目規范下突顯嚴重
3.不好去管理這些任務
2.最初想法及實現如下(第一版low版):
1.需要一個對作業的管理,當有新的業務需要定時任務時,程序員只需要創建一個任務對象,然后交給任務管理器就行了
2.任務管理器會執行當前可執行的任務,執行完立馬T掉此任務(設置為不可執行),防止重復執行
3.當被設置為不可執行的任務到了該工作的時間時,需要去喚醒它,讓它繼續執行.
/// <summary> /// 任務對象 /// </summary> public class TaskInfo { /// <summary> /// 是否可執行 /// </summary> public bool IsRun { get { return Enable && DateTime.Now >= StartTime && DateTime.Now < EndTime; } } /// <summary> /// 是否有效 /// </summary> public bool Enable { get; set; } /// <summary> /// 開始執行時間 /// </summary> public DateTime StartTime { get; set; } /// <summary> /// 結束執行時間 /// </summary> public DateTime EndTime { get; set; } /// <summary> /// 任務名稱 /// </summary> public string TaskName { get; set; } /// <summary> /// 任務處理的業務 /// </summary> public Func<object, object> Job { get; set; } }
/// <summary> /// 任務管理器 /// </summary> public class TaskMgt { /// <summary> /// 任務集合 /// </summary> static List<TaskInfo> TaskCollection = new List<TaskInfo>(); /// <summary> /// 添加任務 /// </summary> /// <param name="taskInfo"></param> public static void Add(TaskInfo taskInfo) { if (!ContainTask(taskInfo.TaskName)) TaskCollection.Add(taskInfo); } /// <summary> /// 檢測任務是否存在 /// </summary> /// <param name="taskName"></param> /// <returns></returns> public static bool ContainTask(string taskName) { if (string.IsNullOrEmpty(taskName)) return false; return TaskCollection.Find(a => a.TaskName.Equals(taskName, StringComparison.CurrentCultureIgnoreCase)) != null; } /// <summary> /// T除任務 /// </summary> /// <param name="taskName"></param> public static void Remove(string taskName) { if (ContainTask(taskName)) { var task = TaskCollection.Where(a => a.TaskName.Equals(taskName, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault(); if (task != null) TaskCollection.Remove(task); } } /// <summary> /// 設置任務為不可執行狀態 /// </summary> /// <param name="taskName"></param> public static void SetUnEnable(string taskName) { TaskCollection.ForEach(a => a.Enable = ( a.TaskName.Equals(taskName, StringComparison.CurrentCultureIgnoreCase) ? false : a.Enable ) ); } /// <summary> /// 喚醒任務 /// </summary> public static void SetEnable() { TaskCollection.ForEach(a => a.Enable = ( !a.Enable && (DateTime.Now < a.StartTime || DateTime.Now > a.EndTime) ? true : a.Enable ) ); } public static void Execute() { Task.Factory.StartNew(() => { while (true) { SetEnable();//設置為可執行線程 List<TaskInfo> list = TaskCollection.Where(a => a.IsRun).ToList(); if (list.Count > 0) { foreach (TaskInfo item in list) { Task.Factory.StartNew(() => { item.Job(null); }); SetUnEnable(item.TaskName);//設置任務為不可執行 } } Thread.Sleep(5000); } }); } }
//添加任務 TaskMgt.Add(new TaskInfo { Enable = true, StartTime =任務開始時間, EndTime = 任務結束時間, TaskName = 任務名稱, Job = a => { FansModule.SynchFans(); return null; } }); //執行任務 TaskMgt.Execute();
3.任務對象的數據 可以寫入配置文件,如果改成Linq.Expression去處理每個任務的作業那也可以,正在研究中
還有任務的異常中斷,任務停止都需要完善
4.現在的初版有點low,代碼有點臃腫,最終的想法是做成接口+反射的形式
歡迎各位的指導