回到目录

之前写过一篇文件《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 => * * ; #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(), 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定时单次任务的更多相关文章

  1. DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化

    在DotNetCore出来之后,同时也使用了quartz进行调度中心的设计,将它做到docker里方便部署,在之前的quartz版本里支持配置文件的方式,而现在不支持了,我们应该去想一下,为什么不去支 ...

  2. java 多线程——quartz 定时调度的例子

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  3. 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出

    1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法   Shiro框架内部整合好缓存管理器, ...

  4. Quartz定时调度框架

    Quartz定时调度框架CronTrigger时间配置格式说明 CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年 ...

  5. spring利用javamail,quartz定时发送邮件 <转>

    原文地址:spring利用javamail,quartz定时发送邮件 <转>作者:物是人非 spring提供的定时发送邮件功能,下面是一个简单的例子以供大家参考,首先从spring配置文件 ...

  6. Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群

    Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群 >>>>>>>>>>>>>> ...

  7. DotNetCore跨平台~文章索引~永久更新

    本索引目录主要包括仓储大叔对dotnet core架构的研究与知识积累,从2016年开始进行撰写,到今天已经有一年多了,其中有一些小知识,小技巧,小应用,希望给大家在开发时一些启发,也希望dotnet ...

  8. DotNetCore跨平台~Dapper的使用

    回到目录 Dapper作为小型ORM的代表作品被我们应用到了dotnet core的项目中,下面将把自己在项目中使用dapper进行curd操作的过程写一下,后期可能会遇到一些问题,大叔也会在这个系列 ...

  9. DotNetCore跨平台~聊聊中间件

    回到目录 在进行.net core平台之后,我们如果希望在请求过程中添加一些事件是非常容易的,你可以把这些事件做成一个中间件Middleware,然后这些中间件就会以Http pipeline的管道方 ...

随机推荐

  1. jQuery全选、全不选、反选的简洁写法【实例】

    全选方面的功能几乎是每个需要列表展示的网站所必不可少的,当然此功能也有很多种写法,现在介绍一下,比较简洁易懂的写法: <input type="checkbox" name= ...

  2. salesforce零基础学习(七十七)队列的实现以及应用

    队列和栈简单的区别为栈是后进先出,队列是先进先出.队列也是特殊的线性表,所以队列也分为顺序存储结构和链式存储结构.本篇主要描述顺序存储结构. 我们先假定一个队列里有5个元素,当我们添加新元素时,添加到 ...

  3. Git版本控制系统之基本使用

    最早是通过接触著名的开源社区Github了解到Git的,但一直没有系统学习过.这次下定决心从头到尾系统的学一学,也将学习过程记录于此,供大家批驳.本篇文章先从以下几个方面简单了解一下Git: Git的 ...

  4. SSD的传输总线、传输协议、传输接口

    前言:关于SSD,有众多总线类型.协议类型.接口类型,每个接口还包括不同型号,在这里花点时间全部整理一下,整理日期2017-08-08. 1.传输总线 总线就像一条公路,公路上的车好比总线上的电信号: ...

  5. 【FAQ系列】:DB服务器产生大量物理读问题优化思路

    一 [现象] 1.7点到9点IO监控指标util特别高,如下: 2 .查看读写情况:读产生很高的物理IO,如下 [分析]:对比其他服务器,buffer pool都是80G,正常情况下热点数据都是从bu ...

  6. Dom的增删查改以及常用事件

    dom的增删查改 // 查 var _input = document.getElementById('_input'); var _div = document.getElementsByClass ...

  7. android 适配器 BaseAdapter 的学习

    昨天晚上看了下ArrayAdapter,和SimpleAdapter,今天早上起来看完了球赛,又继续要开始学习了,适配器除了前面的两种,还有一种常用的就是BaseAdapter,他是一个抽象类.事实上 ...

  8. 开源社交系统ThinkSNS+ V0.8.0 正式发布(一期功能版本)

    智士软件旗下开源sns社交系统ThinkSNS即将进入10周年,推出并行两代系统ThinkSNSV4和ThinkSNS+,以专业易用的技术源码输出,驱动互联网社交软件建设及创业,使用ThinkSNS改 ...

  9. 创建第一个简单的AI分类器

    from sklearn import tree# 第一个简单的分类器features = [[140, 1], [130, 1], [150, 0], [170, 0]] #列表左边的变量代表水果的 ...

  10. iOS之网络请求NSURLSession剖析

    2013年的WWDC大会上,苹果推出了NSURLSession,对Foundation URL加载系统进行了彻底的重构,提供了更丰富的API来处理网络请求,如:支持http2.0协议.直接把数据下载到 ...