概述
Quartz.NET 实现了3个具体的触发器类,SimpleTrigger 简单地在某一时间重复执行多少次,NthIncludedDayTrigger 在每一年、月、周的第几天(Nth)执行作业,CronTrigger 使用 Unix 平台下的'cron-like’表达式来实现非常灵活的触发时间。
SimpleTrigger
它有一个起始时间和结束时间,起始时间触发器触发,过了结束时间触发器停止触发。时间间隔 Interval,触发次数 RepeatCount。
如果一个作业,在指定的时间点执行一次,或者间隔时间内重复执行,SimpleTrigger就可以满足这样的要求。简而言之,2005年1月13日11点23分54秒触发,每10分钟触发5次。
注:间隔时间为TimeSpan.Zero时,会导致同时触发(并发)。
SimpleTrigger有几个不同的构造器:
public SimpleTrigger( string name, string group, DateTime startTimeUtc, NullableDateTime endTime endTimeUtc, int repeatCount, TimeSpan repeatInterval)SimpleTrigger Example 1 - 从现在开始10分钟后触发一次
SimpleTrigger trigger = new SimpleTrigger("myTrigger", null, DateTime.UtcNow.AddSeconds(10), null, 0, TimeSpan.Zero);SimpleTrigger Example 2 - 每60分钟响应一次,立即执行
SimpleTrigger trigger2 = new SimpleTrigger("myTrigger", null, DateTime.UtcNow, null, SimpleTrigger.RepeatIndefinitely, TimeSpan.FromSeconds(60));SimpleTrigger Example 3 - 每10分钟响应一次,40分钟后开始
SimpleTrigger trigger = new SimpleTrigger("myTrigger", "myGroup", DateTime.UtcNow, DateTime.UtcNow.AddSeconds(40), SimpleTrigger.RepeatIndefinitely, TimeSpan.FromSeconds(10));SimpleTrigger Example 4 - 2002年3月17日上午10点30分响应,重复5次(共6次触发),每次之间有30分钟间隔
DateTime startTime = new DateTime(2002, 3, 17, 10, 30, 0).ToUniversalTime(); SimpleTrigger trigger = new SimpleTrigger("myTrigger", null, startTime, null, 5, TimeSpan.FromSeconds(30));
花点时间再看看别的SimpleTrigger构造器,您会发现那个对您最方便。
SimpleTrigger过时触发
CronTrigger
CronTrigger 使用 UNIX 下的“Cron-like” 表达式,实际上用起来感觉它很像正则表达式,可以匹配任意时间,这是体现它灵活性的地方。它的规则如下:
Cron 表达式包括以下 7 个字段(1 个可选)
秒 分 小时 月内日期 月 周内日期 年(可选)
表达式的每个数值域都是一个有最大值和最小值的集合,如:秒域和分钟域的集合是0-59,日期域是1-31,月份域是1-12。注意:秒、分、小时字段是从小到大排序的,这是西方人的习惯,所以在使用的时候要小心,不要颠倒过来。
允许值及对应表见表1。
表1. Cron 表达式允许值及对应表
字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 月内日期 1-31 , - * ? / L W C 月 1-12 或者 JAN-DEC , - * / 周内日期 1-7 或者 SUN-SAT , - * ? / L C # 年(可选) 留空, 1970-2099 , - * / 特殊字符意义对应表见表2。
表2. Cron 表达式特殊字符意义对应表
特殊字符
意义
*
匹配所有的值。如:*在分钟的字段域里表示 每分钟
?
只在日期域和星期域中使用。它被用来指定“非明确的值”
-
指定一个范围。如:“10-12”在小时域意味着“10点、11点、12点”
,
指定几个可选值。如:“MON,WED,FRI”在星期域里表示“星期一、星期三、星期五”
/
指定增量。如:“0/15”在秒域意思是没分钟的0,15,30和45秒。“5/15”在分钟域表示没小时的5,20,35和50。符号“*”在“/”前面(如:*/10)等价于0在“/”前面(如:0/10)
L
表示day-of-month和day-of-week域,但在两个字段中的意思不同,例如day-of-month域中表示一个月的最后一天。如果在day-of-week域表示‘7’或者‘SAT’,如果在day-of-week域中前面加上数字,它表示一个月的最后几天,例如‘6L’就表示一个月的最后一个星期五
W
只允许日期域出现。这个字符用于指定日期的最近工作日。例如:如果你在日期域中写 “15W”,表示:这个月15号最近的工作日。所以,如果15号是周六,则任务会在14号触发。如果15好是周日,则任务会在周一也就是16号触发。如果是在日期域填写“1W”即使1号是周六,那么任务也只会在下周一,也就是3号触发,“W”字符指定的最近工作日是不能够跨月份的。字符“W”只能配合一个单独的数值使用,不能够是一个数字段,如:1-15W是错误的
LW
L和W可以在日期域中联合使用,LW表示这个月最后一周的工作日
#
只允许在星期域中出现。这个字符用于指定本月的某某天。例如:“6#3”表示本月第三周的星期五(6表示星期五,3表示第三周)。“2#1”表示本月第一周的星期一。“4#5”表示第五周的星期三
C
允许在日期域和星期域出现。这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历”关联,则等价于所有包含的“日历”。如:日期域是“5C”表示关联“日历”中第一天,或者这个月开始的第一天的后5天。星期域是“1C”表示关联“日历”中第一天,或者星期的第一天的后1天,也就是周日的后一天(周一)
示例:
"0 0 0 1 1 ?” 每年元旦1月1日 0 点触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发"0 0-5 14 * * ?" 每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
触发器
像Job一样,触发器相对来说还是比较容易实现的。但是要充分利用Quartz.Net,还需要透彻理解触发器的几个自定义选项。早先我们提到过,有几个不同类型的触发器,可以选择不同类型的触发器来满足不同作业的需要。
Calendars
namespace Quartz {public interface ICalendar { string Description { get; set; } ICalendar CalendarBase { set; get; } bool IsTimeIncluded(DateTime timeUtc); DateTime GetNextIncludedTimeUtc(DateTime timeUtc); } }
cal.AddExcludedDate(someDate);
sched.AddCalendar( "myHolidays" , cal, false );
// fire every one hour interval
Trigger trigger = TriggerUtils.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTimeUtc = TriggerUtils.GetEvenHourDate(DateTime.Now);
trigger.Name = "myTrigger1" ;
trigger.CalendarName = "myHolidays" ;
// .. schedule job with trigger
// fire every day at 08:00
Trigger trigger2 = TriggerUtils.MakeDailyTrigger(8, 0);
// begin immediately
trigger.StartTimeUtc = DateTime.UtcNow;
trigger2.Name = "myTrigger2" ;
trigger2.CalendarName = "myHolidays" ;
// .. schedule job with trigger2
Priority
Note: 当一个Trigger被恢复的时候,也是按照他们原来的优先级来恢复的。
Priority Example// All three Triggers will be scheduled to fire 5 minutes from now. DateTime d = DateTime.UtcNow.AddMinutes(5); Trigger trig1 = new SimpleTrigger("T1", "MyGroup", d); Trigger trig2 = new SimpleTrigger("T2", "MyGroup", d); Trigger trig3 = new SimpleTrigger("T3", "MyGroup", d); JobDetail jobDetail = new JobDetail("MyJob", "MyGroup", typeof(NoOpJob)); // Trigger1 does not have its priority set, so it defaults to 5 sched.ScheduleJob(jobDetail, trig1); // Trigger2 has its priority set to 10 trig2.JobName = jobDetail.Name; trig2.Priority = 10; sched.ScheduleJob(trig2); // Trigger2 has its priority set to 1 trig3.JobName = jobDetail.Name; trig3.Priority = 1; sched.ScheduleJob(trig3); // Five minutes from now, when the scheduler invokes these three triggers // they will be allocated worker threads in decreasing order of their
// priority: Trigger2(10), Trigger1(5), Trigger3(1)
过时触发Misfire Instructions
TriggerUtils - 让Triggers更容易
Trigger Listeners监听器
Trigger能够像Job一样,可以把监听器注册到Trigger中,实现了接口TriggerListener的对象就可以接收到Trigger触发时的通知。
CronTrigger
如果需要像日历一样重复发生的作业调度的话,CronTriggers就比特别指定间隔时间的SimpleTrigger,更有用。运用CronTrigger, 可以设定的作业调度像,每周五下午,每工作日的上午9点,每周1、2、5的上午9点到10点。
和SimpleTrigger一样, 有效的CronTrigger有一个开始时间,一个当调度不再继续的结束时间,结束时间是可选的。
Cron Expressions表达式
Cron-Expressions是用来配置CronTrigger实例的。 Cron-Expressions是由7个子字符串表达式组成,用来详细描述schedule的。这些表达式以空格分开:
- Seconds
- Minutes
- Hours
- Day-of-Month
- Month
- Day-of-Week
- Year (optional field)
如一个完整的"0 0 12 ? * WED"表示"每周三晚上12"。
'/'字符可以表示成递增的值。如, 如果分钟的字段上'0/15', 表示每15分钟,从0分钟开始。如果分钟的字段上是'3/20',则表示在一个小时中每20分钟、起点是3。换句话说,在分钟的字段上'3,23,43',与之等效。
'?'字符,可以用在一个月的某天,一个星期的某天。是不特指的意思。当在这两个字段中,不特指的时候很方便使用。下面的CronTriger API中将有详细阐述。
'L'字符串,可以用在一个月的某天,一个星期的某天。是"last"的缩写。但在两个字段中表达的意思是不一样的。例如"L"在月份的某天时,一个月的最后一天,30,31,28。如果在工作日的某天时,只是表示"7"或者"SAT"。但是如果在其他值后面,用在工作日字段中的话,即表示“那个月最后一个周几”。
'W'字符串,可以用来指定一个月的第几天那个工作日。"15W",表示某月的第15天那个工作日。
'#'字符串,可以用来指定一个月的第几个工作日。"6#3" 或者"FRI#3",表示一个月的第3个星期5。.
CronTrigger过时触发
下面介绍CronTrigger的过时触发。 这些过时触发定义在常量MisfireInstruction.CronTrigger中:
- DoNothing
- FireOnceNow
所有触发器都有MisfireInstrution.SmartPolicy过时触发, 且作为缺省的过时触发。这种策略'smart policy'可在CronTrigger这里,以理解为 MisfireInstruction.CronTrigger.FireOnceNow。CronTrigger.UpdateAfterMisfire()方法,在后续有更纤细的阐述。
TriggerListeners and JobListeners
Listeners是用来监听在调度作业有执行动作的对象。TriggerListeners用来接收和triggers相关的事件,JobListeners用来接收和作业有关系的事件.Trigger相关的事件: 触发器触发,触发器过期触发,触发器结束。
ITriggerListener接口public interface ITriggerListener {string Name { get; } void TriggerFired(Trigger trigger, JobExecutionContext context); bool VetoJobExecution(Trigger trigger, JobExecutionContext context); void TriggerMisfired(Trigger trigger); void TriggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode); }
作业相关的时间包括: 作业执行提示,作业结束提示。
IJobListener接口public interface IJobListener {string Name { get; } void JobToBeExecuted(JobExecutionContext context); void JobExecutionVetoed(JobExecutionContext context); void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException); }
用自己的Listeners
创建listener很简单, 创建一个继承ITriggerListener或者IJobListener接口的一个对象。Listeners在调度运行时注册,通过Name属性指定的名称。可以注册成"global" 或者 "non-global"。全局listeners接收所有触发器/作业,non-global监听器接收通过GetTriggerListenerNames() 或者 GetJobListenerNames()获得的事件。
listeners在调度运行的时候注册的,不是与作业和触发器一起存放在JobStore中。jobs与triggers,只是存放那些与之相关的坚听器的名称。因此,每次应用运行时,listeners是需要在调度中重新注册的。
向 Scheduler 添加 JobListenerscheduler.AddGlobalJobListener(myJobListener);or
scheduler.AddJobListener(myJobListener);
在Listeners不常在Quartz.Net中使用,但是如果需要事件提示就随手可见,不需要作业明示的提醒应用。
最后
以上就是幸福山水为你收集整理的Quartz.NET--Trigger 触发器 触发器 CronTrigger TriggerListeners and JobListeners的全部内容,希望文章能够帮你解决Quartz.NET--Trigger 触发器 触发器 CronTrigger TriggerListeners and JobListeners所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复