任务调度系统Quartz.net详解2-Scheduler、Calendar及Listener

任务调度系统Quartz.net详解2-Scheduler、Calendar及Listener

Scheduler

调度器scheduler是Quartz中的独立工作容器,所有的Trigger和Job都需要注册到scheduler中才能工作。我们可以通过SchedulerFactory来获取scheduler实例。如下:

csharp 复制代码
//1.获取默认的标准Scheduler引用
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
//2.通过代码配置scheduler
 NameValueCollection properties = new NameValueCollection
            {
                //scheduler的名字
                ["quartz.scheduler.instanceName"] = "MyScheduler",
                // 设置线程池中线程个数为20个
                ["quartz.threadPool.threadCount"] = "20",
                ["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz",
                //JobStore类型为内存存储
                ["quartz.jobStore.type"] = "Quartz.Simpl.RAMJobStore, Quartz"
            };
ISchedulerFactory factroy = new StdSchedulerFactory(properties);
IScheduler scheduler= await factroy .GetScheduler();

scheduler常用的方法

csharp 复制代码
		  scheduler.Start();//start让调度线程启动
          scheduler.PauseJob(JobKey.Create("jobname", "groupname"));//暂停job
          scheduler.ResumeJob(JobKey.Create("jobname", "groupname"));//重新启动job
          scheduler.DeleteJob(JobKey.Create("jobname", "groupname"));//删除job
          scheduler.PauseTrigger(new TriggerKey("triggername", "groupname"));//暂停trigger
          scheduler.ResumeTrigger(new TriggerKey("triggername", "groupname"));//重新启动trigger
          scheduler.UnscheduleJob(new TriggerKey("triggername", "groupname"));//删除trigger
          scheduler.GetTriggersOfJob(JobKey.Create("jobname", "groupname"));//获取一个job的所有key    
          scheduler.Standby();  //暂停所有的触发器,可通过shceduler.Start()重启
          scheduler.Shutdown(); //关闭scheduler,释放资源。通过Shutdown()关闭后,不能通过Start()重启
          scheduler.GetMetaData();//获取scheduler的元数据
          scheduler.Clear();//清空容器中所有的IJob,ITrigger

多任务调度

csharp 复制代码
//调度多个任务
Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>> triggersAndJobs = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>>();
         triggersAndJobs.Add(job1, new List<ITrigger>() { trigger1,trigger2});
         triggersAndJobs.Add(job2, new List<ITrigger>() { trigger3});
         await scheduler.ScheduleJobs(triggersAndJobs, true);

Calendar

Calendar主要作用就是为了排除Trigger中一些特定的时间节点.

使用Calendar的流程是:首先获取一个Calendar实例,然后将Calendar注册到scheduler容器中,在将Calendar绑定到触发器上即可

csharp 复制代码
 //通过调度工厂获取一个调度器实例
 StdSchedulerFactory factory = new StdSchedulerFactory();
 IScheduler scheduler = factory.GetScheduler().Result;
//创建job
 IJobDetail Job1 = JobBuilder.Create<MyJob>().Build();
//获取一个Calendar实例
DailyCalendar calendar = new DailyCalendar(DateBuilder.DateOf(19, 0, 0).DateTime, DateBuilder.DateOf(21, 0, 0).DateTime);//设置19-21执不执行

//将calendar加入到scheduler中
//最后两个参数是是否替换同名的calendar
//是否更新已有触发器的日历
scheduler.AddCalendar("mycal", calendar, true, true);
//创建触发器
ITrigger trigger1 = TriggerBuilder
                   .Create() //获取TriggerBuilder
                             //.StartAt(DateBuilder.TodayAt(01,34,00)) //开始时间,今天1点34分0秒(hh,mm,ss)
                   .StartNow() //也可以直接现在执行
                   .ForJob(job2) //触发器关联的任务
                   .WithPriority(1) //优先级,触发时间一样时,优先级大的先执行
                   .WithCalendarIntervalSchedule(x => x.WithIntervalInMonths(1))
    				//把Calendar绑定到trigger
                   .ModifiedByCalendar("mycal")
                   .Build(); //利用TriggerBuilder创建ITrigger

Quartz.net中一共提供了六种Calendar,六种Calendar的用法大同小异,列举如下:

csharp 复制代码
		【1】.DailyCalendar 用于排除一天中的某一段时间
            DailyCalendar calendar = new DailyCalendar(DateBuilder.DateOf(19, 0, 0).DateTime, DateBuilder.DateOf(23, 0, 0).DateTime);//21~23点不执行


            【2】.WeeklyCalendar 用于排除一周中的某几天
            WeeklyCalendar calendar = new WeeklyCalendar();
            calendar.SetDayExcluded(DayOfWeek.Sunday, true);//周日不执行 
            //注:如果想让周日恢复执行,执行代码:  calendar.SetDayExcluded(DayOfWeek.Sunday, false);

            【3】.HolidayCalendar 用于排除某些日期
            HolidayCalendar calendar = new HolidayCalendar();
            calendar.AddExcludedDate(DateTime.Parse("2018/1/2")); //2018年1月2号不执行
            //注:如果想让2019/1/9恢复执行,执行代码:  calendar.RemoveExcludedDate(DateTime.Parse("2018/1/2"));

            【4】.MonthlyCalendar 用于排除每个月的某天*************************************
            MonthlyCalendar calendar = new MonthlyCalendar();
            calendar.SetDayExcluded(8,true); //每个月的8号不执行
            //注:如果想让8号恢复执行,执行代码:  calendar.SetDayExcluded(8, false);

            【5】AnnualCalendar 用于排除一年中的某些天*************************************
            AnnualCalendar calendar = new AnnualCalendar();
            calendar.SetDayExcluded(DateTime.Parse("2018/1/2"), true);//每年1月2号不执行
            //注:如果想让1月8号恢复执行,执行代码:   calendar.SetDayExcluded(DateTime.Parse("2018/1/2"),true);

            【6】.CronCalendar 用于排除cron表达式表示的时间***************************
            CronCalendar calendar = new CronCalendar("* * * 2 1 ?"); //每年的1月2号不执行

Listener

JobListener用于在Job执行前、后和被拒绝时执行一些动作,和Asp.net中的filter很相似。

csharp 复制代码
//需要集成相应的IJobListener接口
//TriggerListener和JobListener类似
public class MyJobListener : IJobListener
{
    public string Name => "hello joblisener";
    //job被拒绝时执行
    public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
    {
        await Task.Run(() => { });
    }
    //job开始前执行
    public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
    {
        await Task.Run(() =>
        {
            Console.WriteLine("myjob-------------begin");
        });
    }
    //job完成后执行
    public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
    {
        await Task.Run(() =>
        {
            Console.WriteLine("myjob---------------end");
            Console.WriteLine();
        });
    }
}

设置scheduler的ListenerManager

csharp 复制代码
//start让调度线程启动
//调度线程可以从jobstore中获取快要执行的trigger,然后获取trigger关联的job,执行job
scheduler.Start();
//myJobListener监控所有的job
scheduler.ListenerManager.AddJobListener(new MyJobListener(), GroupMatcher<JobKey>.AnyGroup());
//将job和trigger注册到scheduler中
//必须,否则不会执行任务
scheduler.ScheduleJob(job, trigger).Wait();

同理,TriggerListener和JobListener用法类似

相关推荐
团子股股东峥哥2 分钟前
day27-RHEL-访问Linux文件系统
linux·运维·服务器
佳児素花痴╮21 分钟前
Linux IO模型详解:从阻塞到多路复用
linux·运维·服务器
tg_xianheyun25 分钟前
2026BytePlus CDN加速应用场景全面解析
服务器·数据库·阿里云·云计算·cdn·全球访问优化·云直播
朝发如雪28 分钟前
快速掌握Linux(4)(进程)
java·linux·服务器
啦啦啦啦啦zzzz34 分钟前
共享内存的网络聊天室
linux·服务器·网络·c++·网络编程
2401_894915531 小时前
GEO 优化源码性能调优:高并发地域请求缓存与索引优化
java·服务器·网络·数据库·缓存
manongdashu1881 小时前
应对“SEO需要支付一年服务费”的捆绑消费,静态建站配套终身低成本服务器,全程无需额外运维开销。的方法。
运维·服务器·前端·seo·静态网站
2301_780789661 小时前
WAF与Web应用安全的深度融合:从边界防护到业务风控
运维·服务器·网络·云原生·ddos
不会就选b1 小时前
Linux之线程池(二)
linux·运维·服务器
Nontee2 小时前
Quartz 集群 + 策略模式:逾期预警推送系统设计实录
linux·服务器·策略模式