DotNetCore跨平台~Quartz定时单次任务
之前写过一篇文件《DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化》,今天主要把框架优化了一下,支持外部触发,并支持外部将参数以JobDataMap形式进行输入,然后在咱们的Job里进行使用它,故称参数化任务。
Quartz使用场景:
- 定时单次任务:在未来某个时间去执行一次
- 定点任务 :在某个时间去执行,可以是轮询的
- 周期任务 :按某个时间间隔去轮询执行
今天说的外部触发的任务是指第一种,即在未来某个时间点去执行,并且只执行一次。说一下思路,这种任务某个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定时单次任务的更多相关文章
- DotNetCore跨平台~Quartz热部署的福音~监控文件夹的变化
在DotNetCore出来之后,同时也使用了quartz进行调度中心的设计,将它做到docker里方便部署,在之前的quartz版本里支持配置文件的方式,而现在不支持了,我们应该去想一下,为什么不去支 ...
- java 多线程——quartz 定时调度的例子
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- 项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送邮件 5.基于poi实现分区导出
1 Shiro整合ehCache缓存授权信息 当需要进行权限校验时候:四种方式url拦截.注解.页面标签.代码级别,当需要验证权限会调用realm中的授权方法 Shiro框架内部整合好缓存管理器, ...
- Quartz定时调度框架
Quartz定时调度框架CronTrigger时间配置格式说明 CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年 ...
- spring利用javamail,quartz定时发送邮件 <转>
原文地址:spring利用javamail,quartz定时发送邮件 <转>作者:物是人非 spring提供的定时发送邮件功能,下面是一个简单的例子以供大家参考,首先从spring配置文件 ...
- Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群
Spring+quartz集群配置,Spring定时任务集群,quartz定时任务集群 >>>>>>>>>>>>>> ...
- DotNetCore跨平台~文章索引~永久更新
本索引目录主要包括仓储大叔对dotnet core架构的研究与知识积累,从2016年开始进行撰写,到今天已经有一年多了,其中有一些小知识,小技巧,小应用,希望给大家在开发时一些启发,也希望dotnet ...
- DotNetCore跨平台~Dapper的使用
回到目录 Dapper作为小型ORM的代表作品被我们应用到了dotnet core的项目中,下面将把自己在项目中使用dapper进行curd操作的过程写一下,后期可能会遇到一些问题,大叔也会在这个系列 ...
- DotNetCore跨平台~聊聊中间件
回到目录 在进行.net core平台之后,我们如果希望在请求过程中添加一些事件是非常容易的,你可以把这些事件做成一个中间件Middleware,然后这些中间件就会以Http pipeline的管道方 ...
随机推荐
- UITabbarController左右滑动切换标签页
UITabbarController左右滑动切换标签页 每个Tabbar ViewController都要添加如下代码,建议在基类中添加:ViewDidLoadUISwipeGestureRecogn ...
- mybatis 详解(五)------动态SQL
前面几篇博客我们通过实例讲解了用mybatis对一张表进行的CRUD操作,但是我们发现写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ...
- 字符串--hdu--3783--ZOJ
/* Name: 字符串--hdu--3783--ZOJ Author: shen_渊 Date: 17/04/17 20:58 Description: 明天开始刷字符串的题,先来道水题 */ #i ...
- multiset与set
set的含义是集合,它是一个有序的容器,里面的元素都是排序好的,支持插入,删除,查找等操作,就 像一个集合一样.所有的操作的都是严格在logn时间之内完成,效率非常高. set和multiset的 ...
- Sublime Text3使用汇总
Sublime Package Control 功能:安装包管理 简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能 使用:https://sublime.wbond.net/ins ...
- mac使用小提示
1. 升级到serria系统,默认需要长按caps lock 才会锁定,段按会切换输入法.解决方法: 设置--键盘--输入法, 取消勾选"使用大写锁定键切换输入法" 2. 是否显 ...
- Cognos配置管理
--Cognos配置管理 --------------------------2014/03/19 进入配置管理界面: /washome/cognos/c10/bin64 ./cogconfig.sh ...
- 字符串拼接data-id时注意事项
今天测试下一个ajax请求,结果后台接收不到data-id的数据,导致后台无法进行正确的数据库查询. 我的评论页面是使用字符串拼接后,再放到页面里的,其中有关data-id的部分是这样的: '< ...
- angular2 组件交互
1. 组件通信 我们知道Angular2应用程序实际上是有很多父子组价组成的组件树,因此,了解组件之间如何通信,特别是父子组件之间,对编写Angular2应用程序具有十分重要的意义,通常来讲,组件之间 ...
- 为什么我们要使用Async、Await关键字
前不久,在工作中由于默认(xihuan)使用Async.Await关键字受到了很多质问,所以由此引发这篇博文“为什么我们要用Async/Await关键字”,请听下面分解: Async/Await关键字 ...