Quartz.Net的基础使用方法,多任务执行继续扩展
- 2020 年 8 月 10 日
- 笔记
- .NET, 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一个比较简单的扩展,功能上比较粗糙,也算是一点小总结。后续,比如:可视化执行界面、自定义任务的开关操作等,都是可以作为扩展的内容。