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,代码有点臃肿,最终的想法是做成接口+反射的形式
欢迎各位的指导