前一篇随笔讲了Quartz多任务的简单实现html
这一篇,来简单对前一篇进行一下简单的扩展app
看了前一篇的代码会发现,每次新增一个任务还要去GetJobs方法里往任务列表新增一个任务async
有没有一种简单的方法自动往任务列表去添加新增的任务呢?post
从代码能够发现,全部的任务都必须继承IJob接口ui
1 public class Task_1 : IJob
一、咱们定义一个接口IJobBase,继承IJob接口,而且新增一个执行时间间隔的属性url
1 using Quartz; 2 3 namespace HHF.Quartz 4 { 5 public interface IJobBase : IJob 6 { 7 /// <summary> 8 /// 执行时间间隔(秒) 9 /// </summary> 10 int seconds { get; set; } 11 } 12 }
二、使Task_1,Task_2继承IJobBase接口,并实现seconds属性spa
1 public class Task_1 : IJobBase 2 { 3 int s = 5; 4 public int seconds { get { return s; } set { s = value; } } 5 public Task Execute(IJobExecutionContext context) 6 { 7 return Console.Out.WriteLineAsync($"这是任务一,执行时间:{DateTime.Now}"); 8 } 9 }
三、先准备两个实体对象code
1 /// <summary> 2 /// 任务明细 3 /// </summary> 4 public class TaskDetail 5 { 6 public IJobDetail job { get; set; } 7 public string key { get; set; } 8 public int seconds { get; set; } 9 } 10 /// <summary> 11 /// 类明细 12 /// </summary> 13 public class ClassDetail 14 { 15 public Type tasktype { get; set; } 16 public int seconds { get; set; } 17 }
四、根据类名获取类对象的方法htm
1 /// <summary> 2 /// 获取类对象 3 /// </summary> 4 /// <param name="assembly"></param> 5 /// <param name="className"></param> 6 /// <returns></returns> 7 public static object GetClassObj(Assembly assembly, string className) 8 { 9 // 从程序集中获取指定对象类型; 10 Type type = assembly.GetType(className); 11 Object obj = type.Assembly.CreateInstance(type.ToString()); 12 return obj; 13 }
五、获取全部继承IJobBase接口类的方法对象
1 /// <summary> 2 /// 获取全部继承IJob的类 3 /// </summary> 4 /// <returns></returns> 5 public static List<ClassDetail> GetIJobTypes() 6 { 7 var res = new List<ClassDetail>(); 8 //根据反射获取全部继承了IJobBase接口的类 9 var types = AppDomain.CurrentDomain.GetAssemblies() 10 .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IJobBase)))) 11 .ToArray(); 12 if (types.Length > 0) 13 { 14 for (int i = 0; i < types.Length; i++) 15 { 16 // 类对象 17 var obj = GetClassObj(types[i].Assembly, types[i].FullName); 18 // 获取指定名称的属性,执行间隔时间 19 var propertyInfo = types[i].GetProperty("seconds"); 20 // 获取属性值 21 int value = (int)propertyInfo.GetValue(obj, null); 22 23 var entity = new ClassDetail(); 24 entity.tasktype = types[i]; 25 entity.seconds = value; 26 res.Add(entity); 27 } 28 } 29 return res; 30 }
六、生成执行任务集合的方法
1 /// <summary> 2 /// 获取执行的任务集合 3 /// </summary> 4 /// <returns></returns> 5 public static List<TaskDetail> GetJobs() 6 { 7 var list = new List<TaskDetail>(); 8 var types = GetIJobTypes(); 9 if (types.Count > 0) 10 { 11 for (int i = 0; i < types.Count; i++) 12 { 13 var item = types[i]; 14 var key = "job" + i; 15 var task = new TaskDetail(); 16 IJobDetail job = JobBuilder.Create(item.tasktype).WithIdentity("job" + i).Build(); 17 18 task.job = job; 19 task.key = key; 20 task.seconds = item.seconds; 21 22 list.Add(task); 23 } 24 } 25 return list; 26 }
七、再对Run方法进行一点小小的改造
1 /// <summary> 2 /// 任务调度的使用过程 3 /// </summary> 4 /// <returns></returns> 5 public async static Task Run() 6 { 7 // 建立scheduler的引用 8 ISchedulerFactory schedFact = new StdSchedulerFactory(); 9 IScheduler sched = await schedFact.GetScheduler(); 10 11 // 全部任务集合 12 var jobs = TaskCollections.GetJobs(); 13 // 申明一个任务与触发器映射的字典集合 14 var jobAndTriggerMapping = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>>(); 15 // 遍历任务列表 16 foreach (var job in jobs) 17 { 18 // 生成只读的触发器集合 19 var triggers = new ReadOnlyCollection<ITrigger>( 20 new List<ITrigger>(){ 21 TriggerBuilder.Create() 22 .WithIdentity("trigger_" + job.key) 23 .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.seconds).RepeatForever()) 24 .Build() }); 25 26 jobAndTriggerMapping[job.job] = triggers; 27 } 28 29 // 将映射关系包装成制度字典集合 30 var readOnlyjobAndTriggerMapping = new ReadOnlyDictionary<IJobDetail, IReadOnlyCollection<ITrigger>>(jobAndTriggerMapping); 31 32 /* 33 * 使用trigger规划执行任务job 34 *第二个参数replace:若是为true,则指定的触发器或者任务名称已经存在将会替换,不然将抛出异常 35 */ 36 await sched.ScheduleJobs(readOnlyjobAndTriggerMapping, true); 37 38 //启动 scheduler 39 await sched.Start(); 40 }
八、咱们给任务一设置5秒执行间隔,任务二设置7秒执行间隔,启动看一看效果,正常执行
九、咱们再添加一个Task_3,设置执行间隔为10秒看看效果
以上就是对Quartz一个比较简单的扩展,功能上比较粗糙,也算是一点小总结。后续,好比:可视化执行界面、自定义任务的开关操做等,都是能够做为扩展的内容。