前一篇隨筆講了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一個比較簡單的擴展,功能上比較粗糙,也算是一點小總結。後續,好比:可視化執行界面、自定義任務的開關操做等,都是能夠做爲擴展的內容。