Quartz.NET c# 教程 - 课程六:CronTrigger

如果你需要类似日历时间的触发工作: 像 每周五中午, 工作日早上9点, 或者每周一早上9~10点间每隔5分钟之类的, 你可以选择用 CronTriggers.

和 SimpleTrigger 一样, CronTrigger 也有一个 startTime 来指定启动时间和 endTime 来指定结束时间.

Cron Expressions

Cron-Expressions 用来配置 CronTrigger 实例. Cron-Expressions 是一些由 7 个子串组合成的字符串, 用来描述调度时间的细节. 这些子串用空格隔开, 如下:

  • 1. Seconds
  • 2. Minutes
  • 3. Hours
  • 4. Day-of-Month
  • 5. Month
  • 6. Day-of-Week
  • 7. Year (可选)

例如: "0 0 12 ? * WED" - 它表示 "每周三中午 12 点".

每个子串可以包含多个值, 比如上例中的周三(WED), 也可以是: "MON-FRI", "MON, WED, FRI", 甚至 "MON-WED,SAT".

通配符 * 表示该子串的任何可能的值, 所以在 "Month" 子串, 通配符表示每个月, 在 "Day-of-Week" 通配符表示每天.

所有子串都有各自的合法值, 这些值都很明显. 像分和秒, 应该是 0 - 59. Day-of-Month 可以是 0-31 的任意值, 但是要注意所给月份的实际天数. Months 可以是 0 - 11, 或者用 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 和 DEC. Days-of-Week 可以是 1 到 7 (1 = Sunday) 或者 SUN, MON, TUE, WED, THU, FRI 和 SAT.

'/' 用来表示值的增长. 比如在 Minutes, '0/15' 表示从 0 分开始每 15 分钟. 如果是 '3/20' 则表示在该小时内从 03 分起, 每 20 分钟, 或者指定特定时间点 '3,23,43'.

'?' 只有在 day-of-month 和 day-of-week  可以用. 它表示无特定值. 如果你需要给这两个子串中的某一个指定值, 而另一个不想设置任何值, 你就可以用问号. 看下面的例子有说明.

'L' 用于 day-of-month 和 day-of-week 子串. 它是 "last" 的简写. 不过在这两个子串中有不同的意思. 比如, 在子串 day-of-month , 一月份时它表示 31 号, 平年二月份时表示 28 号.在子串 day-of-week 它就表示 "7" 或者 "SAT". 如果 day-of-month 子串的值设为 day-of-week 某个有效值加上"L", 那就表示月的最后一个周几, 比如 "6L" 或者 "SATL" 表示该月的最后一个星期6. 用 "L" 的时候, 最后不要给该子串设置多个值, 否则你自己都有可能看不懂.

'W' 用来表示离给定日期最近的那个工作日. 比如把 day-of-month 设为 "15W", 表示最接近当月 15 号的那个工作日.

'#' 表示当月第几个 XXX 工作日. 比如 day-of-week 设为 "6#3" 或者 "FRI#3" 表示当月第 3 个周五.

Example Cron Expressions

下面是几个表达式的例子和他们表示的意思, 在 CronTrigger 文档中你可以找到更多例子.

CronTrigger 例子1 - 每5分钟

"0 0/5 * * * ?"

CronTrigger 例子2 - 这分钟后 10 秒起, 每五分钟(i.e. 10:00:10 am, 10:05:10 am, etc.).

"10 0/5 * * * ?"

CronTrigger 例子3 - 每周三, 周五 10:30, 11:30, 12:30 和 13:30.

"0 30 10-13 ? * WED,FRI"

CronTrigger 例子4 - 每个月 5 号和 20 号早 8 点和 10 点间每半个小时触发. 注意它不会在 10:00 am 触发, 只在 8:00, 8:30, 9:00 和 9:30 会触发 job. 

"0 0/30 8-9 5,20 * ?"

有些调度时间可能太过于复杂, 以至于没法用单一的表达式来表达这个时间, 比如 "早上 9 点到 10 点间每 5 分钟以及 下午 1 点到 10 点间每 20 分钟". 这时候就给它两个 trigger 触发相同的 job 就好. 

Building CronTriggers

CronTrigger 的构造器还是 TriggerBuilder (填充主属性) 然后是拓展方法 WithCronSchedule  (填充 CronTrigger 的特定属性).

也可以用 CronScheduleBuilder 的静态方法来构造 schedule.

构造 trigger 从每天早上 8点 到夜里 5点每隔一分钟触发一次:

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithCronSchedule("0 0/2 8-17 * * ?")
    .ForJob("myJob", "group1")
    .Build();

构造 trigger 每天早上 10:42 触发一次:

// we use CronScheduleBuilder's static helper methods here
trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(10, 42))
    .ForJob(myJobKey)
    .Build();

或者

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithCronSchedule("0 42 10 * * ?")
    .ForJob("myJob", "group1")
    .Build();

构造 trigger 在和系统默认时区不同的一个时区上的每周三早上 10:42 触发:

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithSchedule(CronScheduleBuilder
        .WeeklyOnDayAndHourAndMinute(DayOfWeek.Wednesday, 10, 42)
        .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")))
    .ForJob(myJobKey)
    .Build();

或者

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithCronSchedule("0 42 10 ? * WED", x => x
        .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Time")))
    .ForJob(myJobKey)
    .Build();

CronTrigger Misfire Instructions

以下指示器用来通知 Quartz , 当一个 CronTrigger 发生 misfire 时它应该执行的动作 (Misfire 在课程四有介绍). 这些指示器是常量, 如下:

  • MisfireInstruction.IgnoreMisfirePolicy
  • MisfireInstruction.CronTrigger.DoNothing
  • MisfireInstruction.CronTrigger.FireOnceNow

所有的 trigger 都可以用指示器 MisfireInstrution.SmartPolicy, 它也是所有 trigger 的默认指示器类型. 对于 CronTrigger, 'smart policy' 指示器的值是 MisfireInstruction.CronTrigger.FireOnceNow. API 文档 CronTrigger.UpdateAfterMisfire() 详细介绍了该行为的细节.

构造 CronTriggers 时, 用拓展方法 来给 cron 的调度器指定指示器:

trigger = TriggerBuilder.Create()
    .WithIdentity("trigger3", "group1")
    .WithCronSchedule("0 0/2 8-17 * * ?", x => x
        .WithMisfireHandlingInstructionFireAndProceed())
    .ForJob("myJob", "group1")
    .Build();

« Lesson 5 | Lesson 7 »

你可能感兴趣的:(C#系列)