Quartz.Net 官方教程 Tutorial 1/3(Jobs 和 Trigger)

根据官网说明

类型 概述
IScheduler 调度类核心接口
IJob 独立实现业务逻辑需要继承的任务接口
IJobDetail 给任务接口定义实例的任务说明类接口
ITrigger 触发器,设置何时出发,周期触发等
JobBuilder 用于创建IJobDetail类,参数为IJob
TriggerBuilder 创建触发器
SchedulerBuilder 调度任务的配置类,可实例出调度类Quartz 3.1版本及以后有效

Jobs 和 Trigger

Job

只需要继承IJob,并实现Task Execute即可

在调度器线程中通过任务的触发器去执行Execute方法,JobExecutionContext通过任务方法传入的调度器的环境信息和执行信息,还有一部分IJObDetail的相关信息。IJobDetail是任务添加在调度中的类,他包含了任务设置,都保存在JobDataMap类中。JobDataMap中存储了任务的相关信息和在创建时设置的相关信息。

  • JobDetail 可以通过JobBuilder进行创建

    IJobDetail job = JobBuilder.Create<HelloJob>()
    	.WithIdentity("myJob", "group1")
    	.Build();
    
  • JobDataMap - IDictionary的实现类

    • 获得JobDataMap中的信息
    // 创建IJobDetail时将需要添加的信息存储起来
    IJobDetail job = JobBuilder.Create<DumbJob>()
    	.WithIdentity("myJob", "group1") // name "myJob", group "group1"
    	// 存储到了JobDataMap中
    	.UsingJobData("jobSays", "Hello World!")
    	.UsingJobData("myFloatValue", 3.141f)
    	.Build();
    // DumbJob类中使用存储的数据
    public class DumbJob : IJob
    {
    	public async Task Execute(IJobExecutionContext context)
    	{
    		JobKey key = context.JobDetail.Key;
            // 调用 context.MergedJobDataMap获得字典实例
    		JobDataMap dataMap = context.JobDetail.JobDataMap;
    		string jobSays = dataMap.GetString("jobSays");
    		float myFloatValue = dataMap.GetFloat("myFloatValue");
    	}
    }
    
    • 使用JobStore存储数据
    JobDataMap dataMap = context.JobDetail.JobDataMap;
    dataMap.add("name1", "value1");
    
    • 标签

      DisallowConcurrentExecution 不允许并发任务

      PersistJobDataAfterExecution 执行后保存数据

    • IJobDetail方法说明

      WithIdentity 唯一标识,包含名称和群组
      WithDescription 任务描述
      StoreDurably 是否持久化,否:触发器一旦停止则任务会删除
      RequestRecovery 请求恢复,当程序意外终止并启动后,任务会重新执行
    • JobExecutionException IJob.Execute()抛出的异常

Trigger

触发器主要用于对于调度任务的触发,主要分为ISimpleTrigger和ICronTrigger

触发器也可以有JobDataMap类

StartTimeUtc : 执行时间

EndTimeUtc :结束时间

priority :触发器优先级(默认为5,越大优先级越高)

MisfireInstruction :只读,未执行指令,表示因为特殊原因应该执行而未执行的作业

Calendar :日历设置,用于排除执行范围中的特定日期

// 日历起名 
const string calendarName = "myHolidayCalendar";
// 第一种写法
q.AddCalendar<HolidayCalendar>(
    name: calendarName,
    replace: true,
    updateTriggers: true,
    // 排除的日期
    x => x.AddExcludedDate(new DateTime(2023, 1, 29))
);
q.AddTrigger(t => t
    .WithIdentity("Daily Trigger")
    .ForJob(jobKey)
    .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
    .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
    .WithDescription("my awesome daily time interval trigger")
    // 排除的日期名称
    .ModifiedByCalendar(calendarName)
);
// 第二种写法
HolidayCalendar cal = new HolidayCalendar();
// 排除的日期列表
cal.AddExcludedDate(new DateTime(2023, 1, 29));
await sched.AddCalendar(calendarName, cal, false);
ITrigger t = TriggerBuilder.Create()
    .WithIdentity("myTrigger")
    .ForJob("myJob")
    .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(9, 30))
    // 排除的日期名称
    .ModifiedByCalendar("myHolidays") // but not on holidays
    .Build(); 
  • SimpleTrigger

    1. SimpleTrigger执行周期设置

    只执行一次或者按照时间执行多次

    ISimpleTrigger example = (ISimpleTrigger)TriggerBuilder.Create()
    	// 唯一主键并放在trigger-group群组中
        .WithIdentity("trigger-name", "trigger-group")
        // 执行的任务是job-group群组的job-name任务
        .ForJob("job-name", "job-group")
        // 执行方式(触发器内容设置)
        .WithSimpleSchedule(o =>
        {
        	// 每个五分钟执行一次,一共执行5次 
            o.WithRepeatCount(5)
                .WithInterval(TimeSpan.FromMinutes(5));
        })
        .Build();
    
    • 某个时间点执行

      // startTime 时开始执行
      .StartAt(startTime)
      
    • 重复执行

      .WithSimpleSchedule(x => x
      		// 每10s执行一次
              .WithIntervalInSeconds(10)
              // 循环10次,因此一共执行11次
              .WithRepeatCount(10))
      
    • 延迟执行

      // 5分钟后执行
      .StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute)) 
      
    • 循环执行,直到某个时间点

      .WithSimpleSchedule(x => x
      	// 每5分钟执行一次
          .WithIntervalInMinutes(5)
          // 重复执行
          .RepeatForever())
      // 22:00:00结束
      .EndAt(DateBuilder.DateOf(22, 0, 0))
      
    • 从下一个小时开始重复执行

      // 从下一个小时开始 
      .StartAt(DateBuilder.EvenHourDate(null)) 
      // 每两个小时重复执行一次
      .WithSimpleSchedule(x => x
          .WithIntervalInHours(2)
          .RepeatForever())
      
    1. SimpleTrigger方法说明

      var trigger = TriggerBuilder.Create()
          .WithIdentity("trigger1", "group1")
          .StartAt(runTime)
          .WithSimpleSchedule(x=>x
              .WithIntervalInMinutes(5)
              .RepeatForever()
              // 未执行策略(失火策略)有效
              .WithMisfireHandlingInstructionFireNow()
              // 重启计划并重新计算剩余的计划数
              .WithMisfireHandlingInstructionNowWithRemainingCount()
              // 计算剩余的计划数
              .WithMisfireHandlingInstructionNextWithRemainingCount()
              // 忽略未执行策略(失火策略)MisfireInstruction失效
              .WithMisfireHandlingInstructionIgnoreMisfires()
              // 立即重新计算
              .WithMisfireHandlingInstructionNowWithExistingCount()
              // 重新计划下一个
              .WithMisfireHandlingInstructionNextWithExistingCount())
      .Build();
      
  • CronTrigger

    var example = TriggerBuilder.Create()
        .WithIdentity("trigger-name", "trigger-group")
        .ForJob("job-name", "job-group")
        // 秒 分 时 日 月 年
        // 每年的6月份每天的每个小时的23分45秒都执行一次
        .WithCronSchedule("45 23 * * 6 ?") //官网给出的45 23 * * 6 貌似不对
        .Build();
    
    1. cron参数

      • cron赋值

        .WithCronSchedule("0 0/2 8-17 * * ?")
        
      • 代码自带的cron赋值

        // 方法1
        .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(10, 42))
        // 方法2
        .WithCronSchedule("0 42 10 * * ?")
        
      • 使用其他时区的时间定时

        .WithSchedule(CronScheduleBuilder
            .WeeklyOnDayAndHourAndMinute(DayOfWeek.Wednesday, 10, 42)
            //设置时区
            .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Central America Standard Tcime")))
        
    2. CronTrigger特有方法

      ITrigger trigger = TriggerBuilder.Create()
          .WithIdentity("trigger3", "group1")
          .WithCronSchedule("0 0/2 8-17 * * ?", x => x
          	// 忽略未执行策略
          	.WithMisfireHandlingInstructionIgnoreMisfires()
          	// 策略未执行时什么也不干
          	.WithMisfireHandlingInstructionDoNothing()
          	// 启用未执行策略
              .WithMisfireHandlingInstructionFireAndProceed())
          .ForJob("myJob", "group1")
          .Build();
      
posted @ 2023-01-29 18:15  摧残一生  阅读(278)  评论(0编辑  收藏  举报