Quartz.Net的基礎使用方法,多工執行繼續擴充套件

暢飲無緒發表於2020-08-10

前一篇隨筆講了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一個比較簡單的擴充套件,功能上比較粗糙,也算是一點小總結。後續,比如:視覺化執行介面、自定義任務的開關操作等,都是可以作為擴充套件的內容。

相關文章