Quartz.Net的基础使用方法,多任务执行继续扩展

前一篇随笔讲了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一个比较简单的扩展,功能上比较粗糙,也算是一点小总结。后续,比如:可视化执行界面、自定义任务的开关操作等,都是可以作为扩展的内容。

posted @ 2020-08-10 23:52  畅饮无绪  阅读(1291)  评论(1编辑  收藏  举报