Quartz.Net间隔N周/日/年定时触发器写法总结
Posted OMI天空
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Quartz.Net间隔N周/日/年定时触发器写法总结相关的知识,希望对你有一定的参考价值。
由于近日在定时器中对特殊的规则(既不能通过表达式直接体现的)的用法初步汇总:
本次使用的Quartz.Net的版本号:2.6
1.触发器测试验证
public class TestQuartz /// <summary> /// 间隔N周定时触发器写法测试 /// </summary> public static void TestWeeklyIntervalGetFireTimeAfter() DateTimeOffset startCalendar = DateBuilder.DateOf(1, 10, 0, 1, 1, 2023); var yearlyTrigger = new CalendarIntervalTriggerImpl StartTimeUtc = startCalendar, RepeatIntervalUnit = IntervalUnit.Week, RepeatInterval = 2, PreserveHourOfDayAcrossDaylightSavings = true ; DateTimeOffset targetCalendar = startCalendar.AddDays(7 * 2); // jump 24 weeks (4 intervals) IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(yearlyTrigger, null, 24); DateTimeOffset fifthTime = fireTimes[1]; // get the fifth fire time Assert.AreEqual(targetCalendar, fifthTime, "Week increment result not as expected."); /// <summary> /// 间隔N天定时触发器写法测试 /// </summary> public static void TestDayIntervalGetFireTimeAfter() DateTimeOffset startCalendar = DateBuilder.DateOf(1, 10, 0, 1, 1, 2023); var yearlyTrigger = new CalendarIntervalTriggerImpl StartTimeUtc = startCalendar, RepeatIntervalUnit = IntervalUnit.Day, RepeatInterval = 1, PreserveHourOfDayAcrossDaylightSavings = true ; DateTimeOffset targetCalendar = startCalendar.AddDays(1); // jump 24 weeks (4 intervals) IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(yearlyTrigger, null, 365); DateTimeOffset fifthTime = fireTimes[1]; // get the fifth fire time Assert.AreEqual(targetCalendar, fifthTime, "Week increment result not as expected."); /// <summary> /// 间隔N月定时触发器写法测试 /// </summary> public static void TestMonthIntervalGetFireTimeAfter() DateTimeOffset startCalendar = DateBuilder.DateOf(23, 20, 0, 1, 1, 2023); var yearlyTrigger = new CalendarIntervalTriggerImpl StartTimeUtc = startCalendar, RepeatIntervalUnit = IntervalUnit.Month, RepeatInterval = 1, PreserveHourOfDayAcrossDaylightSavings = true ; DateTimeOffset targetCalendar = startCalendar.AddMonths(1); // jump 24 weeks (4 intervals) IList<DateTimeOffset> fireTimes = TriggerUtils.ComputeFireTimes(yearlyTrigger, null, 12); DateTimeOffset fifthTime = fireTimes[1]; // get the fifth fire time Assert.AreEqual(targetCalendar, fifthTime, "Week increment result not as expected.");
注册工具实现
/// <summary> /// 定时器管理工具类 /// </summary> /// <typeparam name="T"></typeparam> public class QuartzManager<T> where T : class, IJob #region 变量 /// <summary> /// scheduler工厂 /// </summary> private static ISchedulerFactory schedulerFactory = new StdSchedulerFactory(); /// <summary> /// Job群组名 /// </summary> private static String JOB_GROUP_NAME = "JOBGROUP_NAME"; /// <summary> /// 触发器群组名 /// </summary> private static String TRIGGER_GROUP_NAME = "TRIGGERGROUP_NAME"; private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion #region 添加,删除,修改Job方法 /// <summary> /// 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="pStrCronExpress">触发器表达式</param> public static void addJob(string pStrJobName, string pStrCronExpress, IDictionary<string, object> pDictionary) try IScheduler sched = schedulerFactory.GetScheduler(); // 创建任务 IJobDetail job = JobBuilder.Create<T>() .WithIdentity(pStrJobName, JOB_GROUP_NAME) .Build(); // 创建触发器 ITrigger trigger = TriggerBuilder.Create() .WithIdentity(pStrJobName, TRIGGER_GROUP_NAME) .WithCronSchedule(pStrCronExpress) .Build(); //给任务传参数 foreach (KeyValuePair<string, object> kvp in pDictionary) job.JobDataMap.Put(kvp.Key, kvp.Value); sched.ScheduleJob(job, trigger); logger.Info("加载了服务:" + pStrJobName); catch (Exception e) logger.Info("加载异常:" + e.Message); throw new Exception(e.Message); /// <summary> /// 添加一个定时任务,使用自定义规则 /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="doDailyTime">自定义执行情况</param> /// <param name="doCalendar">自定义执行情况</param> /// <param name="startTimeUtc">触发器执行起点时间</param> public static void addJob(string pStrJobName, Action<DailyTimeIntervalScheduleBuilder> doDailyTime , Action<CalendarIntervalScheduleBuilder> doCalendar, DateTimeOffset startTimeUtc, IDictionary<string, object> pDictionary) try IScheduler sched = schedulerFactory.GetScheduler(); // 创建任务 IJobDetail job = JobBuilder.Create<T>() .WithIdentity(pStrJobName, JOB_GROUP_NAME) .Build(); // 创建触发器 ITrigger trigger = TriggerBuilder.Create() .WithIdentity(pStrJobName, TRIGGER_GROUP_NAME) .WithCalendarIntervalSchedule(d => if (doCalendar != null) doCalendar(d); ) .WithDailyTimeIntervalSchedule(d => if (doCalendar != null) doDailyTime(d); ) .StartAt(startTimeUtc) .Build(); //给任务传参数 foreach (KeyValuePair<string, object> kvp in pDictionary) job.JobDataMap.Put(kvp.Key, kvp.Value); sched.ScheduleJob(job, trigger); logger.Info("加载了服务:" + pStrJobName); catch (Exception e) logger.Info("加载异常:" + e.Message); throw new Exception(e.Message); /// <summary> /// 定时器高级注册应用 /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="myTrigger">自定义</param> /// <param name="pDictionary">自定义参数</param> public static void addJob<TiggerImpl>(string pStrJobName, Func<TiggerImpl, ITrigger> myTrigger, IDictionary<string, object> pDictionary) where TiggerImpl : CalendarIntervalTriggerImpl try IScheduler sched = schedulerFactory.GetScheduler(); // 创建任务 IJobDetail job = JobBuilder.Create<T>() .WithIdentity(pStrJobName, JOB_GROUP_NAME) .Build(); // 创建触发器 ITrigger trigger = myTrigger(Activator.CreateInstance<TiggerImpl>()); //给任务传参数 foreach (KeyValuePair<string, object> kvp in pDictionary) job.JobDataMap.Put(kvp.Key, kvp.Value); sched.ScheduleJob(job, trigger); logger.Info("加载了服务:" + pStrJobName); catch (Exception e) logger.Info("加载异常:" + e.Message); throw new Exception(e.Message); /// <summary> /// 移除一个任务(使用默认的任务组名,触发器名,触发器组名) /// </summary> /// <param name="pStrJobName">任务名称</param> public static void RemoveJob(string pStrJobName) try IScheduler sched = schedulerFactory.GetScheduler(); JobKey jobKey = new JobKey(pStrJobName); TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME); sched.PauseTrigger(triggerKey);// 停止触发器 sched.UnscheduleJob(triggerKey);// 移除触发器 sched.DeleteJob(jobKey);// 删除任务 logger.Info("卸载了服务:" + pStrJobName); catch (Exception e) logger.Info("卸载异常:" + e.Message); throw new Exception(e.Message); /// <summary> /// 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) /// </summary> /// <param name="pStrJobName">任务名</param> /// <param name="pStrCronExpress">触发器表达式</param> public static void ModifyJobTime(string pStrJobName, string pStrCronExpress, IDictionary<string, object> pDictionary) try IScheduler sched = schedulerFactory.GetScheduler(); TriggerKey triggerKey = new TriggerKey(pStrJobName, TRIGGER_GROUP_NAME); ICronTrigger trigger = (ICronTrigger)sched.GetTrigger(triggerKey); if (trigger == null) return; RemoveJob(pStrJobName); addJob(pStrJobName, pStrCronExpress, pDictionary); catch (Exception e) throw new Exception(e.Message); #endregion #region 启动,关闭Job /// <summary> /// 启动所有定时任务 /// </summary> public static void startJobs() try IScheduler sched = schedulerFactory.GetScheduler(); sched.Start(); catch (Exception e) throw new Exception(e.Message); /// <summary> /// 关闭所有定时任务 /// </summary> public static void ShutdownJobs() try IScheduler sched = schedulerFactory.GetScheduler(); if (!sched.IsShutdown) sched.Shutdown(); catch (Exception e) throw new Exception(e.Message); #endregion
定制注册示例
public partial class PubDataService : ServiceBase public PubDataService() InitializeComponent(); protected override void OnStart(string[] args) try LogHelper.WriteLog("服务开始启动!"); //定时生成病害检查自动任务数据连接服务(0.5时/次) QuartzManager<StcDiseaseManagerTask>.addJob("StcDiseaseManagerTask", ConfigHelper.GetAppSetting("cornExpress01"), new Dictionary<string, object>()); QuartzManager<StcDiseaseManagerTask>.startJobs();//定时生成二次注浆区段自动任务数据连接服务(1月/次) #region 验证已通过 QuartzManager<KeySectionSecondGroutSectionTask>.addJob<CalendarIntervalTriggerImpl>("KeySectionSecondGroutSectionTask", d => d.StartTimeUtc = DateBuilder.DateOf(23, 20, 0, 1, 1, 2023); d.RepeatIntervalUnit = IntervalUnit.Month; d.RepeatInterval = 1; d.PreserveHourOfDayAcrossDaylightSavings = true; return d; , new Dictionary<string, object>()); #endregion QuartzManager<KeySectionSecondGroutSectionTask>.startJobs(); //定时生成技术状况2级及以上影响区段自动任务数据连接服务(1月/次) QuartzManager<KeySectionTechnicalValueSectionTask>.addJob("KeySectionTechnicalValueSectionTask", ConfigHelper.GetAppSetting("cornExpress04"), new Dictionary<string, object>()); QuartzManager<KeySectionTechnicalValueSectionTask>.startJobs(); //定时生成技术状况评定计算连接服务-单环评定(1日/次) QuartzManager<TecConditionSingleDataTask>.addJob("TecConditionSingleDataTask", ConfigHelper.GetAppSetting("cornExpress05"), new Dictionary<string, object>()); QuartzManager<TecConditionSingleDataTask>.startJobs(); //定时生成技术状况评定计算连接服务-区段评定(2周/次) #region 验证已通过 QuartzManager<TecConditionStcSectionTask>.addJob<CalendarIntervalTriggerImpl>("TecConditionStcSectionTask", d => d.StartTimeUtc = DateBuilder.DateOf(23, 30, 0, 1, 1, 2023); d.RepeatIntervalUnit = IntervalUnit.Week; d.RepeatInterval = 2; d.PreserveHourOfDayAcrossDaylightSavings = true; return d; , new Dictionary<string, object>()); #endregion QuartzManager<TecConditionStcSectionTask>.startJobs(); LogHelper.WriteLog("服务启动成功!"); catch (Exception ex) LogHelper.WriteLog("服务启动失败," + ex.Message, ex); protected override void OnStop() LogHelper.WriteLog("服务开始关闭!"); QuartzManager<StcDiseaseManagerTask>.ShutdownJobs(); QuartzManager<StcDiseaseManagerTask>.RemoveJob("StcDiseaseManagerTask"); QuartzManager<ElectroManagerTask>.ShutdownJobs(); QuartzManager<ElectroManagerTask>.RemoveJob("ElectroManagerTask"); QuartzManager<KeySectionSecondGroutSectionTask>.ShutdownJobs(); QuartzManager<KeySectionSecondGroutSectionTask>.RemoveJob("KeySectionSecondGroutSectionTask"); QuartzManager<KeySectionTechnicalValueSectionTask>.ShutdownJobs(); QuartzManager<KeySectionTechnicalValueSectionTask>.RemoveJob("KeySectionTechnicalValueSectionTask"); QuartzManager<TecConditionSingleDataTask>.ShutdownJobs(); QuartzManager<TecConditionSingleDataTask>.RemoveJob("TecConditionSingleDataTask"); LogHelper.WriteLog("服务关闭成功!");
Quartz.Net系列:Trigger之CalendarIntervalScheduleBuilder详解
所有方法图
CalendarIntervalScheduleBuilder方法
在SimpleScheduleBuilder基础上实现了日、周、月、年
WithInterval:指定要生成触发器的时间单位和间隔。
WithIntervalInHours:指定要生成触发器的间隔按小时来
WithIntervalInMinutes:指定要生成触发器的间隔按分钟来
WithIntervalInSeconds:指定要生成触发器的间隔按秒来
WithIntervalInDays:指定要生成触发器的间隔按日来
WithIntervalInWeeks:指定要生成触发器的间隔按周来
WithIntervalInMonths:指定要生成触发器的间隔按月来
WithIntervalInYears:指定要生成触发器的间隔按年来
var trigger = TriggerBuilder.Create().WithCalendarIntervalSchedule(c=>c .WithInterval(1, IntervalUnit.Millisecond) .WithIntervalInSeconds(1) .WithIntervalInMinutes(1) .WithIntervalInHours(1) .WithIntervalInDays(1) .WithIntervalInWeeks(1) .WithIntervalInMonths(1) .WithIntervalInYears(1)).Build();
注:按最后一个设定时间为准
最后指定给字段interval和intervalUnit,那么前面就会覆盖
在不指定间隔的时候默认是1,间隔单位是一天
public class CalendarIntervalScheduleBuilder : ScheduleBuilder<ICalendarIntervalTrigger> { private int interval = 1; private IntervalUnit intervalUnit = IntervalUnit.Day; private int misfireInstruction = MisfireInstruction.SmartPolicy; private TimeZoneInfo timeZone; private bool preserveHourOfDayAcrossDaylightSavings; private bool skipDayIfHourDoesNotExist; }
/// <summary> /// Supported interval units used by <see cref="ICalendarIntervalTrigger" />. /// </summary> public enum IntervalUnit { Millisecond, Second, Minute, Hour, Day, Week, Month, Year }
/// <summary> /// Specify the time unit and interval for the Trigger to be produced. /// </summary> /// <remarks> /// </remarks> /// <param name="interval">the interval at which the trigger should repeat.</param> /// <param name="unit"> the time unit (IntervalUnit) of the interval.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithInterval(int interval, IntervalUnit unit) { ValidateInterval(interval); this.interval = interval; intervalUnit = unit; return this; } /// <summary> /// Specify an interval in the IntervalUnit.SECOND that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInSeconds">the number of seconds at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInSeconds(int intervalInSeconds) { ValidateInterval(intervalInSeconds); interval = intervalInSeconds; intervalUnit = IntervalUnit.Second; return this; } /// <summary> /// Specify an interval in the IntervalUnit.MINUTE that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInMinutes">the number of minutes at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInMinutes(int intervalInMinutes) { ValidateInterval(intervalInMinutes); interval = intervalInMinutes; intervalUnit = IntervalUnit.Minute; return this; } /// <summary> /// Specify an interval in the IntervalUnit.HOUR that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInHours">the number of hours at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInHours(int intervalInHours) { ValidateInterval(intervalInHours); interval = intervalInHours; intervalUnit = IntervalUnit.Hour; return this; } /// <summary> /// Specify an interval in the IntervalUnit.DAY that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInDays">the number of days at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInDays(int intervalInDays) { ValidateInterval(intervalInDays); interval = intervalInDays; intervalUnit = IntervalUnit.Day; return this; } /// <summary> /// Specify an interval in the IntervalUnit.WEEK that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInWeeks">the number of weeks at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInWeeks(int intervalInWeeks) { ValidateInterval(intervalInWeeks); interval = intervalInWeeks; intervalUnit = IntervalUnit.Week; return this; } /// <summary> /// Specify an interval in the IntervalUnit.MONTH that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInMonths">the number of months at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInMonths(int intervalInMonths) { ValidateInterval(intervalInMonths); interval = intervalInMonths; intervalUnit = IntervalUnit.Month; return this; } /// <summary> /// Specify an interval in the IntervalUnit.YEAR that the produced /// Trigger will repeat at. /// </summary> /// <remarks> /// </remarks> /// <param name="intervalInYears">the number of years at which the trigger should repeat.</param> /// <returns>the updated CalendarIntervalScheduleBuilder</returns> /// <seealso cref="ICalendarIntervalTrigger.RepeatInterval" /> /// <seealso cref="ICalendarIntervalTrigger.RepeatIntervalUnit" /> public CalendarIntervalScheduleBuilder WithIntervalInYears(int intervalInYears) { ValidateInterval(intervalInYears); interval = intervalInYears; intervalUnit = IntervalUnit.Year; return this; }
InTimeZone:设置时区
var trigger = TriggerBuilder.Create().WithCalendarIntervalSchedule(c => c.InTimeZone(TimeZoneInfo.Local)).Build();
以上是关于Quartz.Net间隔N周/日/年定时触发器写法总结的主要内容,如果未能解决你的问题,请参考以下文章