前一篇隨筆講了Quartz多工的簡單實現
Quartz.Net的基礎使用方法,多工執行
這一篇,來簡單對前一篇進行一下簡單的擴充套件
看了前一篇的程式碼會發現,每次新增一個任務還要去GetJobs方法裡往任務列表新增一個任務
有沒有一種簡單的方法自動往任務列表去新增新增的任務呢?
從程式碼可以發現,所有的任務都必須繼承IJob介面
1 public class Task_1 : IJob
1、我們定義一個介面IJobBase,繼承IJob介面,並且新增一個執行時間間隔的屬性
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 }
2、使Task_1,Task_2繼承IJobBase介面,並實現seconds屬性
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 }
3、先準備兩個實體物件
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 }
4、根據類名獲取類物件的方法
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 }
5、獲取所有繼承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 }
6、生成執行任務集合的方法
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 }
7、再對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 }
8、我們給任務一設定5秒執行間隔,任務二設定7秒執行間隔,啟動看一看效果,正常執行
9、我們再新增一個Task_3,設定執行間隔為10秒看看效果
以上就是對Quartz一個比較簡單的擴充套件,功能上比較粗糙,也算是一點小總結。後續,比如:視覺化執行介面、自定義任務的開關操作等,都是可以作為擴充套件的內容。