您的位置:首页 > 其它

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

2020-08-10 23:52 1141 查看

前一篇随笔讲了Quartz多任务的简单实现

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

这一篇,来简单对前一篇进行一下简单的扩展

看了前一篇的代码会发现,每次新增一个任务还要去GetJobs方法里往任务列表新增一个任务

有没有一种简单的方法自动往任务列表去添加新增的任务呢?

 

从代码可以发现,所有的任务都必须继承IJob接口

public class Task_1 : IJob

1、我们定义一个接口IJobBase,继承IJob接口,并且新增一个执行时间间隔的属性

using Quartz;

namespace HHF.Quartz
{
public interface IJobBase : IJob
{
/// <summary>
/// 执行时间间隔(秒)
/// </summary>
int seconds { get; set; }
}
}

2、使Task_1,Task_2继承IJobBase接口,并实现seconds属性

public class Task_1 : IJobBase
{
int s = 5;
public int seconds { get { return s; } set { s = value; } }
public Task Execute(IJobExecutionContext context)
{
return Console.Out.WriteLineAsync($"这是任务一,执行时间:{DateTime.Now}");
}
}

3、先准备两个实体对象

/// <summary>
/// 任务明细
/// </summary>
public class TaskDetail
{
public IJobDetail job { get; set; }
public string key { get; set; }
public int seconds { get; set; }
}
/// <summary>
/// 类明细
/// </summary>
public class ClassDetail
{
public Type tasktype { get; set; }
public int seconds { get; set; }
}

4、根据类名获取类对象的方法

/// <summary>
/// 获取类对象
/// </summary>
/// <param name="assembly"></param>
/// <param name="className"></param>
/// <returns></returns>
public static object GetClassObj(Assembly assembly, string className)
{
// 从程序集中获取指定对象类型;
Type type = assembly.GetType(className);
Object obj = type.Assembly.CreateInstance(type.ToString());
return obj;
}

5、获取所有继承IJobBase接口类的方法< 56c /p>

/// <summary>
/// 获取所有继承IJob的类
/// </summary>
/// <returns></returns>
public static List<ClassDetail> GetIJobTypes()
{
var res = new List<ClassDetail>();
//根据反射获取所有继承了IJobBase接口的类
var types = AppDomain.
ad0
CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IJobBase))))
.ToArray();
if (types.Length > 0)
{
for (int i = 0; i < types.Length; i++)
{
// 类对象
var obj = GetClassObj(types[i].Assembly, types[i].FullName);
// 获取指定名称的属性,执行间隔时间
var propertyInfo = types[i].GetProperty("seconds");
// 获取属性值
int value = (int)propertyInfo.GetValue(obj, null);

var entity = new ClassDetail();
entity.tasktype = types[i];
entity.seconds = value;
res.Add(entity);
}
}
return res;
}
6、生成执行任务集合的方法

/// <summary>
/// 获取执行的任务集合
/// </summary>
/// <returns></returns>
public static List<TaskDetail> GetJobs()
{
var list = new List<TaskDetail>();
var types = GetIJobTypes();
if (types.Count > 0)
{
for (int i = 0; i < types.Count; i++)
{
var item = types[i];
var key = "job" + i;
var task = new TaskDetail();
IJobDetail job = JobBuilder.Create(item.tasktype).WithIdentity("job" + i).Build();

task.job = job;
task.key = key;
task.seconds = item.seconds;

list.Add(task);
}
}
return list;
}

7、再对Run方法进行一点小小的改造

/// <summary>
/// 任务调度的使用过程
/// </summary>
/// <returns></returns>
public async static Task Run()
{
// 创建scheduler的引用
ISchedulerFactory schedFact = new StdSchedulerFactory();
IScheduler sched = await schedFact.GetScheduler();

// 所有任务集合
var jobs = TaskCollections.GetJobs();
// 申明一个任务与触发器映射的字典集合
var jobAndTriggerMapping = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>>();
// 遍历任务列表
foreach (var job in jobs)
{
// 生成只读的触发器集合
var triggers = new ReadOnlyCollection<ITrigger>(
new List<ITrigger>(){
TriggerBuilder.Create()
.WithIdentity("trigger_" + job.key)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(job.seconds).RepeatForever())
.Build() });

jobAndTriggerMapping[job.job] = triggers;
}

// 将映射关系包装成制度字典集合
30     var readOnlyjobAndTriggerMapping = new ReadOnlyDictionary<IJobDetail, IReadOnlyCollection<ITrigger>>(jobAndTriggerMapping);

/*
* 使用trigger规划执行任务job
*第二个参数replace:如果为true,则指定的触发器或者任务名称已经存在将会替换,否则将抛出异常
*/
await sched.ScheduleJobs(readOnlyjobAndTriggerMapping, true);

//启动 scheduler
await sched.Start();
40 }

8、我们给任务一设置5秒执行间隔,任务二设置7秒执行间隔,启动看一看效果,正常执行

 

9、我们再添加一个Task_3,设置执行间隔为10秒看看效果

 

 以上就是对Quartz一个比较简单的扩展,功能上比较粗糙,也算是一点小总结。后续,比如:可视化执行界面、自定义任务的开关操作等,都是可以作为扩展的内容。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: