关于Quartz .NET(V3.0.7)的简要说明
0. 任务调度
比如说,财务系统需要在每个月初生成上一个月的财务报表。
比如说,每天或每周固定时间对数据库更新。
比如说,每天定时发送邮件。
这些需要在某个预定的时间点周期性的执行某个特定的任务的功能(也就是任务调度),可以使用任务调度框架——Quartz .NET
Quartz.NET是一个开源的任务调度框架(作业调度框架),是从Java移植过来的,使用较为广泛!
1. Quartz .NET
1.1 基本概念
调度器(Scheduler):存放触发器和定时任务,根据触发器执行定时任务
触发器(Trigger):决定执行时间,执行间隔,运行次数,故触发器用来告诉调度程序作业什么时候触发
任务(Job):需要定时或是周期性执行的任务
使用流程:
创建调度器-->创建任务-->创建触发器-->Job和Trigger注册到调度器-->启动调度器;
1.2 主要接口和对象
接口/类 | 作用 |
---|---|
IScheduler | 调度器接口 |
IJob | 任务接口,将需要定时执行的方法实现在该接口的Excute方法中 |
IJobDetail | 用于定义Job的实例 |
ITrigger | 触发器接口 |
JobBuilder | 任务构造者:用于创建任务实例 |
TriggerBuilder | 触发器构造者:用于创建触发器实例 |
JobDetailImpl | 实现了IJobDetail类 |
JobKey | 任务名 |
TriggerKey | 触发器名 |
其中触发器的类型
触发器最常用的主要有两种:
SimpleTrigger:用于指定任务重复执行的时间间隔
IMutableTrigger:用于指定任务重复执行的具体时间
2. 使用示例
2.0 准备工作
①安装Quartz程序包
当前时间:2020年3月18日 23:20:59,最新版本的Quartz.NET为3.0.7
每次的版本的变化,API变化都好大,所以在这里注明当前的使用版本!
建议使用最新版本,新版本都是异步方法实现的。
NuGet:Install-Package Quartz -Version 3.0.7
②新建TestJob.cs
实现IJob接口
public class TestJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() => Console.WriteLine($"{DateTime.Now}:执行任务了……"));
}
}
2.1 每间隔一定时间间隔执行一次任务
//间隔5s重复一次执行指定的任务
public static async void WithInterval()
{
//-------1.准备调度者
ISchedulerFactory factory = new StdSchedulerFactory(); //创建调度器工厂
IScheduler scheduler = await factory.GetScheduler(); //创建调度者
//-------2.准备任务
JobBuilder jobBuilder = JobBuilder.Create<TestJob>();//创建任务构造者:JobBuilder
IJobDetail job1 = jobBuilder.Build();//创建任务
//-------3.准备触发器
TriggerBuilder triggerBuilder = TriggerBuilder.Create()
.StartNow()//立即生效
.WithSimpleSchedule(x=>x.WithIntervalInSeconds(5)
.RepeatForever()); //创建触发器构造者:TriggerBuilder
ISimpleTrigger trigger = triggerBuilder.WithIdentity("trigger1","group2").Build() as ISimpleTrigger;//创建触发器
//-------4.将任务与触发器添加到调度器中
await scheduler.ScheduleJob(job1, trigger);
await scheduler.Start();//开始执行
}
【代码说明】
示例中使用的而是
ISimpleTrigger
类型的触发器,可以精准的设置任务重复的时间间隔。其中的触发器构造者中的
triggerBuilder.StartNow()
表示触发器立即生效triggerBuilder.StartAt(DateTimeOffset startTimeUtc)
设置触发器生效的时间triggerBuilder.EndAt(DateTimeOffset startTimeUtc)
设置触发器失效的时间其中使用
WithIntervalInSeconds(5)
表示每五秒触发一次任务其他的一些按照小时和天的做间隔,以及明确触发次数的方法都简单明确,根据VS的智能提示即可了解,不一一列举于此!
示例中使用
RepeatForever()
表示重复无穷次,还是可以使用WithRepeatCount()
设置重复的次数的。这里有一个细节问题,比如说,设置执行三次,
WithRepeatCount(3)
,但是注意实际会执行4次
2.3 某天的固定时间点执行任务
Quartz.NET的接口比较繁多,第一个示例中是使用的最基础的方法,下面代码示例将换一种简写的方式。
//每天按照指定的时间点执行任务
public static async void AtHourAndMinute()
{
//创建调度器
IScheduler scheduler = await new StdSchedulerFactory().GetScheduler();
//创建任务
//JobDetailImpl job1 = new JobDetailImpl("TestJob1", "group1", typeo(TestJob))//JobDetailImpl是IJobDetail的实现类
//等价于:
IJobDetail job1 = JobBuilder.Create<TestJob>().WithIdentity("Testjob1""group1").Build();
//创建触发器
IMutableTrigger trigger2job1 = CronScheduleBuilder.DailyAtHourAndMinut(03, 50).Build();//每天更具某时间点重复触发任务
//将任务和触发器添加到调度器中
trigger2job1.Key = new TriggerKey("trigger1");//注意一定要给触发器命名
await scheduler.ScheduleJob(job1, trigger2job1);
//开始执行调度者
await scheduler.Start();
}
【代码说明】
示例中使用的是
IMutableTrigger
类型的触发器通过
CronScheduleBuilder
类的静态方法可以设置触发的具体的某一日设置触发时间为每天的某时某分:
DailyAtHourAndMinut(03, 50)
设置触发时间是一周中的哪几天中的几时几分 :
AtHourAndMinuteOnGivenDaysOfWeek(int hour , int min, params DayOfWeek[] daysOfWeek)
设置触发时间是每月中某天某时某分 :
CronScheduleBuilder.MonthlyOnDayAndHourAndMinute(int dayOfMonth, int hour, int min).Build()
封装好的一些方法还是有一定局限的(但是我自己够用的了),关于其他的一些复杂的周期任务,都是可以使用cron expression,使用cron expression可以定义你能想到的所有触发时间和周期
cron expression什么样?怎么用?例如设置触发的时间是:每年每月的2点18分40秒
CronScheduleBuilder.CronSchedule("40 18 2 ? * * *").WithIdentity("trigger1").Build();
关于cron expression写起来还是有点麻烦的,可以使用一些在线生成器为我们自动的生成期望的表达式。
2.4 封装整个定时任务,并给任务传递参数
前面的示例为了简洁的表示Quartz.NET的一些API的使用,
项目中都是把为定时任务,整个的操作流程封装在一个静态方法中,存放在我们自定义的Job类中
做一个简单的示例:定时发送短信。
自定义Job,实现IJob接口,同时把创建调度器对象,创建触发器和任务封装于其中,作为一个静态方法
class TestJob2 : IJob
{
public async Task Execute(IJobExecutionContext context)
{
try
{
JobDataMap dataMap = context.MergedJobDataMap;
string tag = dataMap.GetString("tag");
string title = dataMap.GetString("title");
string content = dataMap.GetString("content");
string description = dataMap.GetString("description");
string tels = dataMap.GetString("tels");
//执行定时任务:模拟发送短信
await Task.Run(() => Console.WriteLine($"发短信:【{tag}】,{title}:{content },{description},电话:{tels}。"));
//await context.Scheduler.Shutdown();//表示完成当前的定时任务,关闭调度器
//记入日志
Console.WriteLine("执行了一次定时任务,记入日志");
}
catch (Exception ex)
{
//记入日志Log.Error()
Console.WriteLine(ex.Message);
}
}
//将创建定时任务的所有操作封装在此
public static async void SendMessage(string starttime, string cronStr,string tag, string title, string content,string description, string tels)
{
try
{
//创建调度器
IScheduler scheduler = await new StdSchedulerFactory().GetScheduler();
//为任务准备参数
DateTime time = DateTime.Parse(starttime);
JobDataMap jobData = new JobDataMap()
{
new KeyValuePair<string, object>("tag", tag),
new KeyValuePair<string, object>("title", title),
new KeyValuePair<string, object>("content", content),
new KeyValuePair<string, object>("description", description),
new KeyValuePair<string, object>("tels", tels),
};
//创建任务:
//注意可以用时间做组名:DateTime.Now.ToLongDateString()
IJobDetail job = JobBuilder.Create<TestJob2>()
.WithIdentity("Testjob1", "group1")
.SetJobData(jobData)
.Build();
//创建触发器
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("triger1", "group1")
.StartAt(time)//触发器开始时间//.StartNow()现在开始
.WithCronSchedule(cronstr)
.Build();
//将任务和触发器添加到调度器中
await scheduler.ScheduleJob(job, trigger);
await scheduler.Start();
}
catch (Exception ex)
{
//记入日志
Console.WriteLine(ex.Message);
}
}
}
调用:
public static async void PackageJob()
{
//从系统当前时间,每隔5s,发送一条短信:【新闻】,新冠病毒,治愈者越来越多,普天同庆,10086。
await Task.Run(() => TestJob2.SendMessage(DateTime.Now .ToString(),"/5 * * ? * *","新闻", "新冠病毒", "治愈者越来越多", "普天同庆", "10086"));
}
【代码说明】
使用
JobDataMap
类型存放需要传递到IJob
接口的Excute(IJobExecutionContext context)
方法中在
JobDataMap
中以键值对的方式存放数据,jobDataMao.Add("key",value)
在定义Job的时候,使用触发器对象中的方法
jobBuilder.SetJobData(jobData)
将JobDataMap类型的数据传递到任务中使用
JobDataMap dataMap = context.MergedJobDataMap;
获取传递到Excute()中的JobDataMap类型的数据使用
string value = dataMap.GetString("key");
获取数据因为定时任务的是延时的执行的,所以切记一定要把每个周期中执行的定时任务记入到日志中,便于维护管理!
注意,因为实现了IJob接口的任务类,其Excute()方法是在一个单独的线程中运行的,所以其异常的处理也在Excute()中使用try……catch……进行处理
BTW:在MVC项目中使用Quartz .NET,直接在Global.asax.cs中的Application_Start()运行封装好的定时任务即可
注意:使用Quartz.NET中的Job,是无法实现任何关于Web的相关操作
2.5 关于调度器的一些说明
一个调度器中可以调度多个方法
使用
scheduler.ScheduleJob(job,trigger)
将指定的任务和触发器添加到指定的调度器中,可以多次添加,从而实现一个调度器中调度多个任务但是有一点要注意:一个任务可以有多个触发器,但是一个触发器只能对应一个任务
调度器可以添加任务,那么就一定是可以移除任务的
//停止触发器
await scheduler.PauseTrigger(triggerKey);
//移除触发器
await scheduler.UnscheduleJob(triggerKey);
//删除任务
await scheduler.DeleteJob(jobkey);
调度器可以开始运行,那么就一定停止运行:
context.Scheduler.Shutdown();
表示完成当前的定时任务,关闭调度器
2.6 关于监听器
Undone……
可参考监听器:JobListeners/TriggerListeners/SchedulerListeners
参考及示例代码下载
监听器:Quartz.NET使用教程
Quartz(Java)源码:Quartz 源码解析
远程管理及可视化操作: ASP.NET MVC5 实现基于Quartz.NET任务调度
配置方式1:Quartz.NET文档 入门教程
配置方式2:Quartz.Net定时任务简单实用(实例)
Cron Expression:Cron Expression Generator
封装任务和传参:NET作业调度(定时任务)-Quartz.Net
关于Quartz .NET(V3.0.7)的简要说明的更多相关文章
- 【Gamma】“北航社团帮”测试报告——小程序v3.0
目录 测试计划.过程和结果 后端测试--单元测试与覆盖率 后端测试--压力测试 展示部分数据 平均数据 前端测试--小程序v3.0 新功能 各页面均可正常打开,跳转,回退 授权登录与权限检查 页面数据 ...
- FineUI(专业版)v3.0.0 发布,手机、平板和桌面全支持!
FineUI(专业版)v3.0.0 已经正式发布,全面支持手机.平板和桌面! 自 2008 年 4 月发布第一个版本,我们持续更新了 126 个版本,拥有 16000 多位注册用户,130 ...
- css sprite,css雪碧图生成工具V3.0更新
V3.0主要改进 1.增加了单独添加单张图片以及删除单张图片的功能 2.增加了生成.sprite文件用以保存雪碧图信息 3.增加了打开.sprite文件功能 什么是css sprite CSS spr ...
- [原创小工具]软件内存、CPU使用率监视,应用程序性能监测器 v3.0 绿色版
应用程序性能监测器 V3.0 更新内容: 1.对一些代码进行了修改,软件本身的性能有所提升. 应用程序性能监测器 V2.0 更新内容: 1.鼠标移动到曲线区域,显示相关的曲线值 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V3.0 版本强势发布
继上个版本“RDIFramework.NET V2.9版本”的推出,受到了重多客户的认可与选择,V2.9版本是非常成功与稳定的版本,感谢大家的认可与长期以来的关注与支持.V3.0版本在V2.9版本的基 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版新增消息管理
在V3.0版本的Web(Mvc.WebForm)与WinForm中我们新增了“消息管理”模块.“消息管理”模块是对框架的所有消息进行管理.通过左侧的消息分类可以查看所选分类的所有消息列表.在主界面上我 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版新增查询引擎管理
欲了解V3.0版本的相关内容可查看下面的链接地址. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版本发布 RDIFramework.NET — 基于.NET的快速信 ...
- RDIFramework.NET平台代码生成器V3.0版本全新发布-更新于20160518(提供下载)
最新版本请转到:RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-08(提供下载) RDIFramework.NET代码生成器V3.0版本修改了针对3.0版本的 ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版新增系统参数管理
欲了解V3.0版本的相关内容可查看下面的链接地址. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.0 版本发布 在V3.0版本的Web(Mvc.WebForm)与WinF ...
随机推荐
- 谁来破解公交WiFi的尴尬困局?
在咖啡馆.饭店坐定,菜单可以待会再看,远远看见服务员迎上来,赶紧先问一句:"这里有无线网吗,密码是多少",和笔者一样养成类似习惯的人越来越多.所以,当公交WiFi"大 ...
- 原生 XMLHttpRequest
一.什么是XMLHttpRequest? XHR英文全名XmlHttpRequest,中文可以解释为可扩展超文本传输请求.Xml可扩展标记语言,Http超文本传输协议,Request请求.XMLHtt ...
- 免密码 ssh 到其它机器
背景:在配置 hadoop 的时候这样设置会比较方便.目标:A 机器上输入 ssh root@B 可以直接访问,不需要输入密码 步骤: 首先在 A 机器上生成密钥对,一路回车 1 ssh-keygen ...
- Python程序运行流程与垃圾回收机制
Python程序运行流程 Python解释器首先将程序将py文件编译成一个字节码对象PyCodeObject(只存在于内存中).(当这个模块的 Python 代码执行完后,就会将编译结果保存到了pyc ...
- 三星HTC价格跳水 安卓旗舰会否崩塌?
安卓旗舰会否崩塌?" title="三星HTC价格跳水 安卓旗舰会否崩塌?"> 官方降价,对于国产手机来说似乎是家常便饭.小米.魅族等,总会时隔几个月就将自家旗舰机 ...
- 查漏补缺:Vector中去重
对于STL去重,可以使用<algorithm>中提供的unique()函数. unique()函数用于去除相邻元素中的重复元素(所以去重前需要对vector进行排序),只留下一个.返回去重 ...
- java23种设计模式 (转)
文章在:http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html 随着自己的开发经验增加以及自己做了很多的 大专栏 jav ...
- 自定义Toast的出现样式
使用下面的方法来获取一个Toast对象: private Toast showShortToast() { if (toast == null) { toast = new Toast(this); ...
- 10分钟进阶SpringBoot - 05. 数据访问之JDBC(附加源码分析+代码下载)
10分钟进阶SpringBoot - 05. 数据访问之JDBC 代码下载:https://github.com/Jackson0714/study-spring-boot.git 一.JDBC是什么 ...
- DotNet Core 使用 StackExchange.Redis 简单封装和实现分布式锁
前言 公司的项目以前一直使用 CSRedis 这个类库来操作 Redis,最近增加了一些新功能,会存储一些比较大的数据,内测的时候发现其中有两台服务器会莫名的报错 Unexpected respons ...