分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

DotNetCore跨平台~Quartz定时单次任务

发布时间:2023-09-06 01:11责任编辑:彭小芳关键词:暂无标签

之前写过一篇文件《DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化》,今天主要把框架优化了一下,支持外部触发,并支持外部将参数以JobDataMap形式进行输入,然后在咱们的Job里进行使用它,故称参数化任务。

Quartz使用场景:

  1. 定时单次任务:在未来某个时间去执行一次
  2. 定点任务  :在某个时间去执行,可以是轮询的
  3. 周期任务  :按某个时间间隔去轮询执行

今天说的外部触发的任务是指第一种,即在未来某个时间点去执行,并且只执行一次。说一下思路,这种任务某个JobBase的子类,它需要重写属性IsSingle,将值设为1表示单次任务,然后在Quartz启动后,它会被立即执行,执行完成后,销毁!

用例:你可以在quartz调度中心里对外公开一些方法,让你的Job依赖于某个时间点和参数去执行,执行一次就停止,这样我们的调度就更加灵活了。

为单次任务添加了IsSingle属性

 ???[DisallowConcurrentExecution()] ???public abstract class JobBase : ISchedulingJob ???{ ???????#region Properties ???????/// <summary> ???????/// 取消资源 ???????/// </summary> ???????public CancellationTokenSource CancellationSource => new CancellationTokenSource(); ???????/// <summary> ???????/// 执行计划,除了立即执行的JOB之后,其它JOB需要实现它 ???????/// </summary> ???????public virtual string Cron => "* * * * * ?"; ???????/// <summary> ???????/// 是否为单次任务,黑为false ???????/// </summary> ???????public virtual bool IsSingle => false; ???????/// <summary> ???????/// Job的名称,默认为当前类名 ???????/// </summary> ???????public virtual string JobName => GetType().Name; ???????/// <summary> ???????/// Job执行的超时时间(毫秒),默认5分钟 ???????/// </summary> ???????public virtual int JobTimeout => 5 * 60 * 1000; ???????#endregion Properties ???????#region Methods ???????/// <summary> ???????/// Job具体类去实现自己的逻辑 ???????/// </summary> ???????protected abstract void ExcuteJob(IJobExecutionContext context, CancellationTokenSource cancellationSource); ???????/// <summary> ???????/// 当某个job超时时,它将被触发,可以发一些通知邮件等 ???????/// </summary> ???????/// <param name="arg"></param> ???????private void CancelOperation(object arg) ???????{ ???????????CancellationSource.Cancel(); ???????????StdSchedulerFactory.GetDefaultScheduler().Result.Interrupt(new JobKey(JobName)); ???????????Console.WriteLine(JobName + "Job执行超时,已经取消,等待下次调度..."); ???????} ???????#endregion Methods ???????#region IJob 成员 ???????public Task Execute(IJobExecutionContext context) ???????{ ???????????Timer timer = null; ???????????try ???????????{ ???????????????timer = new Timer(CancelOperation, null, JobTimeout, Timeout.Infinite); ???????????????Console.WriteLine(DateTime.Now.ToString() + "{0}这个Job开始执行", context.JobDetail.Key.Name); ???????????????if (context.JobDetail.JobDataMap != null) ???????????????{ ???????????????????foreach (var pa in context.JobDetail.JobDataMap) ???????????????????????Console.WriteLine($"JobDataMap,key:{pa.Key},value:{pa.Value}"); ???????????????} ???????????????ExcuteJob(context, CancellationSource); ???????????} ???????????catch (Exception ex) ???????????{ ???????????????Console.WriteLine(this.GetType().Name + "error:" + ex.Message); ???????????} ???????????finally ???????????{ ???????????????if (timer != null) timer.Dispose(); ???????????} ???????????return Task.CompletedTask; ???????} ???????#endregion ???}

统一的加入Job队列的方法

在我们之前的QuartzManager管理者中,我们需要添加对单次任务的支持,这点我们将任务加入到quartz的代码进行了重构,提取到了方法里。

 ???????/// <summary> ???????/// 将类型添加到Job队列 ???????/// </summary> ???????/// <param name="type">类型</param> ???????/// <param name="dt">时间点</param> ???????/// <param name="param">参数</param> ???????private static void JoinToQuartz(Type type, DateTimeOffset dt, Dictionary<string, object> param = null) ???????{ ???????????var obj = Activator.CreateInstance(type); ???????????if (obj is ISchedulingJob) ???????????{ ???????????????var tmp = obj as ISchedulingJob; ???????????????string cron = tmp.Cron; ???????????????string name = tmp.JobName; ???????????????var cancel = tmp.CancellationSource; ???????????????var jobDetail = JobBuilder.Create(type) ?????????????????????????????????????????.WithIdentity(name) ?????????????????????????????????????????.Build(); ???????????????if (param != null) ???????????????????foreach (var dic in param) ???????????????????????jobDetail.JobDataMap.Add(dic.Key, dic.Value); ???????????????ITrigger jobTrigger; ???????????????if (tmp.IsSingle) ???????????????{ ???????????????????jobTrigger = TriggerBuilder.Create() ??????????????????????????????????????????????.WithIdentity(name + "Trigger") ??????????????????????????????????????????????.StartAt(dt) ??????????????????????????????????????????????.Build(); ???????????????} ???????????????else ???????????????{ ???????????????????jobTrigger = TriggerBuilder.Create() ???????????????????????????????????????????????.WithIdentity(name + "Trigger") ???????????????????????????????????????????????.StartNow() ???????????????????????????????????????????????.WithCronSchedule(cron) ???????????????????????????????????????????????.Build(); ???????????????} ???????????????StdSchedulerFactory.GetDefaultScheduler().Result.ScheduleJob(jobDetail, jobTrigger, cancel.Token); ???????????????LoggerInfo($"->任务模块{name}被装载...", ConsoleColor.Yellow); ???????????} ???????}

对外公开的参数化接口

而对于外界如果希望再次触发这个单次任务,我们可以在QuartzManager里公开一个方法,用来向当前SchedulerFactory里添加新的Job就可以了,这个方法很简单,可以提供一个默认的时间策略,如默认为1分钟后执行,也可以自己控制时间。

      /// <summary> ???????/// 任务在1分钟之后被执行1次 ???????/// </summary> ???????/// <param name="type"></param> ???????/// <param name="job"></param> ???????/// <param name="param"></param> ???????public static void SignalJob(Type type, Dictionary<string, object> param) ???????{ ???????????SignalJob(type, DateTimeOffset.Now.AddSeconds(10), param); ???????} ???????/// <summary> ???????/// 任务在某个时间之后被执行1次 ???????/// </summary> ???????/// <param name="type"></param> ???????/// <param name="job"></param> ???????/// <param name="offset"></param> ???????/// <param name="param"></param> ???????public static void SignalJob(Type type, DateTimeOffset offset, Dictionary<string, object> param) ???????{ ???????????JoinToQuartz(type, offset); ???????}

那么,现在某个任务调度中心就更加完善了,开发人员在使用时也很简单,只要继承JobBase,或者去实现ISchedulingJob接口就可以了,非常灵活!

感谢各位的阅读!

quartz,dotnet core我们还在继续研究的路上!

DotNetCore跨平台~Quartz定时单次任务

原文地址:http://www.cnblogs.com/lori/p/7525467.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved