作业调度框架Quartz.NET | 大专栏
原文:作业调度框架Quartz.NET | 大专栏 任务调度系统并不是完美的,它会出现任务执行失败的情况。如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助。 要创建一个监听器,只需创建一个实现ITriggerListener或IJobListener接口的对象。然后在运行时向调度程序注册监听器,并且必须为其指定名称(更确切地说,他们必须通过其Name属性来唯一标识自己。) 如截图所示,这里只执行一次。注意观察:触发器监听优先级 > 任务监听优先级
作业调度框架Quartz.NET
前言
Quartz.NET的任务监听系统已经被我运用在已上线的工程中,亲测无坑。Quartz.Listener
关键接口和类
示例应用程序
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;
using System;
using System.Collections.Specialized;
using System.Threading;
using System.Threading.Tasks;
namespace QuarzLis
{
class Program
{
static void Main(string[] args)
{
StartUpJobs.StartUp().GetAwaiter().GetResult();
Console.ReadKey();
}
public static class StartUpJobs
{
public static async Task StartUp()
{
try
{
//第一步:从工厂中获取Scheduler实例
NameValueCollection props = new NameValueCollection();
StdSchedulerFactory factory = new StdSchedulerFactory(props);
IScheduler scheduler = await factory.GetScheduler();
//第二步:然后运行它
await scheduler.Start();
//第三步:定义作业并绑定到HelloJob类,HelloJob类实现IJob接口
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
//UsingJobData 可以用来传参数
.UsingJobData("appKey", "123456QWE")
.UsingJobData("appName", "小熊猫")
.UsingJobData("api", "https://www.baidu.com")
.Build();
//第四步:创建触发器。设定,执行一次作业。
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1") //指定唯一标识,触发器名字,和组名字
//这对于将作业和触发器组织成“报告作业”和“维护作业”等类别非常有用。
//作业或触发器的键的名称部分在组内必须是唯一的
.StartAt(DateBuilder.FutureDate(5, IntervalUnit.Second)) //可以设定在未来的 5 秒钟后触发
.Build();
//第五步:作业与触发器组合,安排任务
await scheduler.ScheduleJob(job, trigger);
//第六步:创建任务监听,用来解决任务执行失败的情况. HelloJob类实现IJobListener接口
IJobListener jobListener = new HelloJob();
// 注: 任务监听是通过 IJobListener.Name 来区分的.以下逻辑避免多个任务监听情况下造成的监听被覆盖.
// a) 获取当前任务监听实例的名称.
var listener = scheduler.ListenerManager.GetJobListener(jobListener.Name);
// b) 通过job.Key 获取该任务在调度系统中的唯一实体
IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(job.Key);
// c) 注意: 任务监听系统中已存在当前任务监听实例,与新添加任务监听的逻辑的区别.
if (listener != null)
{
// 如果已存在该任务监听实例,调用此方法,为该任务监听实例新增监听对象
scheduler.ListenerManager.AddJobListenerMatcher(jobListener.Name, matcher);
}
else
// 任务监听系统中不存在该任务监听实例,则调用此方法新增监听对象
scheduler.ListenerManager.AddJobListener(jobListener, matcher);
//创建触发器监听,触发器监听与任务监听同名也不影响
ITriggerListener triggerListener = new HelloJob();
var triListener = scheduler.ListenerManager.GetTriggerListener(triggerListener.Name);
IMatcher<TriggerKey> triMatcher = KeyMatcher<TriggerKey>.KeyEquals(trigger.Key);
if (triListener != null)
{
scheduler.ListenerManager.AddTriggerListenerMatcher(triggerListener.Name, triMatcher);
}
else
scheduler.ListenerManager.AddTriggerListener(triggerListener, triMatcher);
//可以设置关闭该调度
//await Task.Delay(TimeSpan.FromSeconds(5));
//await scheduler.Shutdown();
}
catch (SchedulerException se)
{
Console.WriteLine(se);
}
}
}
//实现IJobListener 接口,实现 ITriggerListener 接口,这里和 IJob逻辑放在了一起
public class HelloJob : IJob, IJobListener, ITriggerListener
{
private string appKey;
private string appName;
private string appApi;
public string Name
{
get;
}
public HelloJob()
{
this.Name = this.GetType().ToString();
}
public HelloJob(string name)
{
this.Name = name;
}
public async Task Execute(IJobExecutionContext context)
{
JobKey jkey = context.JobDetail.Key;
TriggerKey tKey = context.Trigger.Key;
JobDataMap dataMap = context.MergedJobDataMap;
appKey = dataMap.GetString("appKey"); //通过键值获取数据
appName = dataMap.GetString("appName");
appApi = dataMap.GetString("api");
await Console.Error.WriteLineAsync(
string.Format("[{0}]开始推送:nJobKey:{1}nTriggerKey:{2}nAppKey:{3} appName: {4} , and AppAPI: {5}"
, DateTime.Now.ToLongTimeString(), jkey, tKey, appKey, appName, appApi));
}
#region IJobListener
public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]任务监听,name:{1}|任务执行失败重新执行。"
, DateTime.Now.ToLongTimeString(), Name));
//任务执行失败,再次执行任务
await Execute(context);
}
public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]任务监听,name:{1}|准备执行任务。"
, DateTime.Now.ToLongTimeString(), Name));
}
public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]任务监听,name:{1}|任务执行完成。"
, DateTime.Now.ToLongTimeString(), Name));
}
#endregion
#region ITriggerListener
public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]触发器监听,name:{1}|触发器触发成功。"
, DateTime.Now.ToLongTimeString(), trigger.Key.Name));
}
public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]触发器监听,name:{1}|触发器开始触发。"
, DateTime.Now.ToLongTimeString(), trigger.Key.Name));
}
public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]触发器监听,name:{1}|触发器触发失败。"
, DateTime.Now.ToLongTimeString(), trigger.Key.Name));
}
public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
{
await Console.Error.WriteLineAsync(string.Format("[{0}]触发器监听,name:{1}|可以阻止该任务执行,这里不设阻拦。"
, DateTime.Now.ToLongTimeString(), trigger.Key.Name));
// False 时,不阻止该任务。True 阻止执行
return false;
}
#endregion
}
}
}
实验效果

上篇
Thanks
相关文章
作业调度框架Quartz.NET | 大专栏的更多相关文章
- 作业调度框架Quartz.NET-现学现用-01-快速入门
原文:作业调度框架Quartz.NET-现学现用-01-快速入门 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预的任务在执 ...
- 作业调度框架Quartz.NET-现学现用-01-快速入门 - 简书
原文:作业调度框架Quartz.NET-现学现用-01-快速入门 - 简书 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预 ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. Quar ...
- 作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书
原文:作业调度框架Quartz.NET-现学现用-02-任务监听 - 简书 前言 任务调度系统并不是完美的,它会出现任务执行失败的情况.如果你需要处理任务失败后的逻辑,希望这篇笔记可以为你提供些帮助. ...
- 作业调度框架 Quartz.NET 2.0 StepByStep
注:目前网上诸多介绍Quartz.net的文章,甚至Quartz.net官网上的Tutorial都是1.0版本的,而这个项目在2.0版本对项目进行了比较大规模的修改,使得原有的很多例子都不能运行,故写 ...
- .Net平台开源作业调度框架Quartz.Net
Quartz.NET介绍: Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中. ...
- (转).Net平台开源作业调度框架Quartz.Net
Quartz.NET介绍: Quartz.NET是一个开源的作业调度框架,是OpenSymphony 的 Quartz API的.NET移植,它用C#写成,可用于winform和asp.net应用中. ...
- .NET开源作业调度框架(Quartz.NET和FluentScheduler)实战项目演练
一.课程介绍 明人不说暗话,跟着阿笨一起玩NET .本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享 ...
- java作业调度框架Quartz
在软件开发中,很多时候需要在特定时间的时间执行某些操作,比如每天的凌晨三点.每周的周日.每个月的15号,Apache Quartz就是一个开源的作业调度框架,可以让计划的程序任务一个预定义的日期和时间 ...
随机推荐
- 微信小程序之如何定义页面标题
效果图: 这个标题是在哪里定义的呢?type.js核心代码如下(通常这段代码放在onLoad函数体内): wx.setNavigationBarTitle({ title: "支出类型列表& ...
- jquery数组倒序
倒叙前:var mem = [1, 2, 3]: 倒序后:var men1=[3,2,1]: <script type="text/javascript"> $(fun ...
- disruptor 组件理解
disruptor 中核心组件包括 RingBuffer.Event .EventHandler.Sequence.Sequence Barrier. WaitStrategy.WorkProcess ...
- 爬虫中Requests模块
Requests: 让 HTTP 服务人类 虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “ ...
- PHP 相关性系数计算
相关系数公式 参考:https://baike.baidu.com/item/相关系数 PHP 实现代码 public static function calc($list) { $cv = []; ...
- Java 使用ZkClient操作Zookeeper
目录 ZkClient介绍 导入jar包依赖 简单使用样例 ZkClient介绍 因为Zookeeper API比较复杂,使用并不方便,所以出现了ZkClient,ZkClient对Zookeeper ...
- Laya页面嵌套和Scene.destory导致的Bug
Laya2.1.1.1 参考: 预设使用 Laya给出了相同模块,逻辑代码也相同情况下,使用页面嵌+runtime的使用方案.但是该方案和Laya.Scene.open,Laya.Scene.dest ...
- 开发日记:常用BAT批处理
备份文件:BackupSourceCode.bat ::自动备份当前文件夹 ::by luomg, 21:15 2010-10-13 ::minguiluo@163.com @echo off tit ...
- [LeetCode] 628. Maximum Product of Three Numbers 三个数字的最大乘积
Given an integer array, find three numbers whose product is maximum and output the maximum product. ...
- [LeetCode] 803. Bricks Falling When Hit 打击砖块掉落
We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick will not drop if and only i ...