Quartz.Net

1、簡單的Quartz程序json

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();
            //trigger 
            var trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x
                                                                        .WithIntervalInSeconds(1)//1s鍾執行一次
                                                                        .RepeatForever()//重複執行
                                                                        .Build()).Build();
            
            //添加監聽
            scheduler.ListenerManager.AddJobListener(new MyJobListener(), GroupMatcher<JobKey>.AnyGroup());

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }

        //面向AOP
        public class MyJobListener : IJobListener
        {
            public string Name => "test";

            //job開始執行以前調用
            public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobExecutionVetoed");
            }

            //job每次執行以後調用
            public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobToBeExecuted");
            }

            //job執行結束以後調用
            public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobWasExecuted");
            }
        }
    }

    public class JobTest : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            Console.WriteLine("asd");
        }
    }
}
demo

 

2、 quartz的五大構件async

1. Scheduler [一個大容器]ide

2. job測試

3. triggerui

4. SimpleThreadPool [最終的執行都是要委託給線程池]spa

  10[WorkThread] + 1 [調度線程 QuartzSchedulerThread] => QuarzThread線程

  SimpleThreadPool 默認是10個thread,是在thread上面進行的封裝,不是線程池線程。。。設計

  QuartzSchedulerThread => public override void Run()3d

5. JobStore =>DbStore,RAMStorecode

  timeTriggers 用於獲取最近的trigger的。

 

3、Job詳解 【JobBuilder】

var job = JobBuilder.Create<HelloJob>().Build();

在JobBuilder中執行執行的Action有四種方法。。。 Create 和 OfType

1. Create<T>

寫代碼方便。。

2. Type類型

後期綁定。。。。

Action不是來自解決方案的。。。 可能你要執行的Action來自於其餘的團隊,對方所作的事情就是實現一下IJob接口就能夠了。。。

咱們拿到這個Dll,作反射,直接把job丟給scheduler。。。。

3,StoreDurably方法

設置job是否持久化

默認狀況下: 一旦job沒有相對應的trigger,那麼這個job會被刪除。。。

若是一對一的狀況下,trigger刪除,job也會被刪除。。。

全部的Job,Trigger 都是在RAMJobStore裏面。。。

4,UsingJobData / SetJobData 都是給一個Job添加附加信息。。。

JobDataMap 就是一個字典,用於添加多個信息。。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                                                .StoreDurably(true)
                                                .UsingJobData("username","hunter")//都是給一個Job添加附加信息
                                                .Build();
            //trigger 
            var trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x
                                                                        .WithIntervalInSeconds(1)//1s鍾執行一次
                                                                        .RepeatForever()//重複執行
                                                                        .Build()).Build();
            
            //添加監聽
            scheduler.ListenerManager.AddJobListener(new MyJobListener(), GroupMatcher<JobKey>.AnyGroup());

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }

        //面向AOP
        public class MyJobListener : IJobListener
        {
            public string Name => "test";

            //job開始執行以前調用
            public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobExecutionVetoed");
            }

            //job每次執行以後調用
            public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobToBeExecuted");
            }

            //job執行結束以後調用
            public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobWasExecuted");
            }
        }
    }

    public class JobTest : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            //獲取附加信息
            Console.WriteLine(context.MergedJobDataMap["username"]);
        }
    }
}
demo

 5,WithIdentity:  若是沒有制定,那麼系統會給一個Guid的標識

            if (key == null)
            {
                key = new JobKey(Guid.NewGuid().ToString(), null);
            }        

4、TriggerBuilder

1. StartAt,EndAt,StartNow Trigger觸發的起始時間和結束時間 

DateTimeOffset有時區概念,DateTime沒有時區的概念

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                                                .StoreDurably(true)
                                                .UsingJobData("username","hunter")//都是給一個Job添加附加信息
                                                .Build();

            Console.WriteLine("開始");
            //trigger 
            var trigger = TriggerBuilder.Create()
                                                .StartAt(DateTimeOffset.Now.AddSeconds(1))//開始執行時間
                                                .EndAt(DateTimeOffset.Now.AddSeconds(5))//執行結束時間
                                                .WithSimpleSchedule(x => x
                                                                        .WithIntervalInSeconds(1)//1s鍾執行一次
                                                                        .RepeatForever()//重複執行
                                                                        .Build()).Build();
            
            //添加監聽
            scheduler.ListenerManager.AddJobListener(new MyJobListener(), GroupMatcher<JobKey>.AnyGroup());

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }

        //面向AOP
        public class MyJobListener : IJobListener
        {
            public string Name => "test";

            //job開始執行以前調用
            public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobExecutionVetoed");
            }

            //job每次執行以後調用
            public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobToBeExecuted");
            }

            //job執行結束以後調用
            public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobWasExecuted");
            }
        }
    }

    public class JobTest : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            //獲取附加信息
            Console.WriteLine(context.MergedJobDataMap["username"]);
        }
    }
}
demo

 

2,其餘一些方法

.ForJob(job)//在定義Trigger的時候,就能夠將對應關係作起來
.UsingJobData("aa","abc")//給Job添加附加信息
.WithPriority(1)//默認優先級【5】(優先級數字越大,優先級越高)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                                                .StoreDurably(true)
                                                .UsingJobData("username","hunter")//都是給一個Job添加附加信息
                                                .Build();

            Console.WriteLine("開始");
            //trigger 
            var trigger = TriggerBuilder.Create()
                                                .StartAt(DateTimeOffset.Now.AddSeconds(1))//開始執行時間
                                                .EndAt(DateTimeOffset.Now.AddSeconds(5))//執行結束時間
                                                .ForJob(job)//在定義Trigger的時候,就能夠將對應關係作起來
                                                .UsingJobData("aa","abc")//給Job添加附加信息
                                                .WithPriority(1)//默認優先級【5】(優先級數字越大,優先級越高)
                                                .WithSimpleSchedule(x => x
                                                                        .WithIntervalInSeconds(1)//1s鍾執行一次
                                                                        .RepeatForever()//重複執行
                                                                        .Build()).Build();
            
            //添加監聽
            scheduler.ListenerManager.AddJobListener(new MyJobListener(), GroupMatcher<JobKey>.AnyGroup());

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }

        //面向AOP
        public class MyJobListener : IJobListener
        {
            public string Name => "test";

            //job開始執行以前調用
            public async Task JobExecutionVetoed(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobExecutionVetoed");
            }

            //job每次執行以後調用
            public async Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobToBeExecuted");
            }

            //job執行結束以後調用
            public async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken))
            {
                Console.WriteLine("JobWasExecuted");
            }
        }
    }

    public class JobTest : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            //獲取附加信息
            Console.WriteLine(context.MergedJobDataMap["aa"]);
        }
    }
}
demo

 

5、四大trigger調度器

1,Simplescheduler
特色:只能在時分秒上作輪詢

RepeatForever() 指定觸發器將無限重複
WithInterval(TimeSpan timeSpan) 指定重複間隔(以毫秒爲單位)
WithIntervalInHours(int hours) 指定重複間隔(以小時爲單位)
WithIntervalInMinutes(int minutes) 指定重複間隔(以分鐘爲單位)
WithIntervalInSeconds(int seconds) 以秒爲單位指定重複間隔
WithRepeatCount(int repeatCount) 重複執行次數(repeatCount+1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();

            Console.WriteLine("開始");
            //trigger 
            var trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x
                                                                        .WithIntervalInSeconds(1)
                                                                        .RepeatForever()
                                                                        .Build()).Build();
            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index++, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
demo

 

2, CalendarIntervalSchedule

特色:和日曆相關的輪詢(1天執行一次,一週執行一次,一個月執行一次,一年執行一次)

WithInterval(int interval, IntervalUnit unit) 指定重複間隔
WithIntervalInDays(int intervalInDays) 指定重複間隔(按天)
WithIntervalInHours(int intervalInHours) 指定重複間隔(按小時)
WithIntervalInMinutes(int intervalInMinutes) 指定重複間隔(按分鐘)
WithIntervalInMonths(int intervalInMonths) 指定重複間隔(按月)
WithIntervalInSeconds(int intervalInSeconds) 指定重複間隔(按秒)
WithIntervalInWeeks(int intervalInWeeks) 指定重複間隔(按星期)
WithIntervalInYears(int intervalInYears) 指定重複間隔(按年)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();

            Console.WriteLine("開始");
            //trigger 
            var trigger = TriggerBuilder.Create().WithCalendarIntervalSchedule(x => x
                                                                        .WithIntervalInWeeks(2)//每兩週執行一次
                                                                        .Build()).Build();
            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index++, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
每兩週執行一次

 

3,DailyTimeIntervalScheduleBuilder

OnMondayThroughFriday() 週一至週五執行
OnSaturdayAndSunday() 週六和週日執行
OnEveryDay() 一週全部日子 WithInterval(
int interval, IntervalUnit unit) 指定要生成的觸發器的時間單位和時間間隔。 WithIntervalInHours(int intervalInHours) 指定重複間隔(按天) WithIntervalInMinutes(int intervalInMinutes) 指定重複間隔(按分鐘) WithIntervalInSeconds(int intervalInSeconds) 指定重複間隔(按秒) StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(8, 00) 開始執行時間 EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(20, 00) 結束時間

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();

            Console.WriteLine("開始");

            //30分鐘檢測一次,8點-20點
            //trigger 
            var trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(x => x
                                                            .OnEveryDay()//沒天執行
                                                            .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(8,0))//開始執行時間
                                                            .EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(20,0))//結束執行時間
                                                            .WithIntervalInMinutes(30)//無論何時執行的此程序,都是每30分鐘整點執行一次(例如8:30,13:30)
                                                            .Build()).Build();



            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
8點-20點,30分鐘檢測一次
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();

            Console.WriteLine("開始");

            //天天凌晨2點跑一次
            //trigger 
            var trigger = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(x => x
                                                            .OnEveryDay()//沒天執行
                                                            .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(2,0))//開始執行時間
                                                            .EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(2,1))//結束執行時間
                                                            .WithIntervalInMinutes(30)//巧妙設計,是程序天天只執行一次
                                                            .Build()).Build();

            //注意作一個問題:在測試的時候先調整好計算機時間,在run此程序
            //若是先run程序,在調整時間,會有問題

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
天天凌晨2點跑一次

 

5,WithCronSchedule

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>().Build();

            Console.WriteLine("開始");

            //trigger 
            var trigger = TriggerBuilder.Create().WithCronSchedule("* * * ? * MON").Build();

            //注意作一個問題:在測試的時候先調整好計算機時間,在run此程序
            //若是先run程序,在調整時間,會有問題

            //開始調度
            scheduler.ScheduleJob(job, trigger);
            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
demo

Cron表達式

quartz中的cron表達式和Linux下的很相似,好比 "/5 * * ? * * *"  這樣的7位表達式,最後一位年非必選。

表達式從左到右,依此是秒、分、時、月第幾天、月、周幾、年。下面表格是要遵照的規範:

字段名 容許的值 容許的特殊字符
Seconds 0-59 , - * /
Minutes 0-59 , - * /
Hours 0-23 , - * /
Day of month 1-31 , - * ? / L W
Month 1-12 or JAN-DEC , - * /
Day of week 1-7 or SUN-SAT , - * ? / L #
Year 空, 1970-2099 , - * /

 

 

 

 

 

 

星期一 MON
星期二 TUE
星期三 WED
星期四 THU
星期五 FRI
星期六 SAT
星期天 SUN

特殊字符 解釋
, 或的意思。例:分鐘位 5,10  即第5分鐘或10分都觸發。 
/ a/b。 a:表明起始時間,b頻率時間。 例; 分鐘位  3/5,  從第三分鐘開始,每5分鐘執行一次。
* 頻率。 即每一次波動。    例;分鐘位 *  即表示每分鐘 
- 區間。  例: 分鐘位   5-10 即5到10分期間。 
? 任意值 。   即每一次波動。只能用在DayofMonth和DayofWeek,兩者衝突。指定一個另外一個一個要用?
L 表示最後。 只能用在DayofMonth和DayofWeek,4L即最後一個星期三
W 工做日。  表示最後。 只能用在DayofWeek
# 4#2。 只能用DayofMonth。 某月的第二個星期三  

 

 

 

 

 

 

 

 

 

 

 

 

實例:

天天8-20點間隔28分鐘執行一次:0 0/28 8-20 * * ?"
間隔10秒跑一次:0/10 * 8-20 * * ?
天天8-20天,30分鐘執行一次: 0 0/30 8-20 * * ?
週一到週五凌晨2點執行: 0 0 2 ? * MON-FRI 執行一次

」0 0 10,14,16 * * ?"    天天10點,14點,16點 觸發。

"0 0/5 14,18 * * ?"    天天14點或18點中,每5分鐘觸發 。

"0 4/15 14-18 * * ?"       天天14點到18點期間,  從第四分鐘觸發,每15分鐘一次。

"0 15 10 ? * 6L"        每個月的最後一個星期五上午10:15觸發。

 http://cron.qqe2.com/

6、操做案例

1,trigger先綁定job,而後在執行

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .WithCronSchedule("* * * * * ?").Build();

            //使用這句話的前提是job必須是持久化的,不然只能使用下面那句話
            scheduler.ScheduleJob(trigger);
            //scheduler.ScheduleJob(job,trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
demo

2,job操做

List<JobDetailImpl> jobList = new List<JobDetailImpl>();

            //第一步:獲取全部的job信息
            var jobKeySet = scheduler.GetJobKeys(GroupMatcher<JobKey>.AnyGroup());

            foreach (var jobKey in jobKeySet)
            {
                var jobDetail = (JobDetailImpl)scheduler.GetJobDetail(jobKey);

                jobList.Add(jobDetail);
            }

            var json = JsonConvert.SerializeObject(jobList.Select(i => new
            {
                i.Name,
                i.Group,
                i.Durable,
                i.JobDataMap,
                i.Description,
                TriggerList = string.Join(",", scheduler.GetTriggersOfJob(new JobKey(i.Name, i.Group))
                                    .Select(m => m.Key.ToString()))
            }));
查詢job
var exists = scheduler.CheckExists(new JobKey(jobRequest.JobName,
                                                              jobRequest.JobGroupName));

                if (exists && !jobRequest.IsEdit)
                {
                    return Json("已經存在同名的Job,請更換!");
                }

                var assemblyName = jobRequest.JobFullClass.Split('.')[0];
                var fullName = jobRequest.JobFullClass;
                var dllpath = Request.MapPath(string.Format("~/bin/{0}.dll", assemblyName));

                //須要執行的job名稱
                var jobClassName = Assembly.LoadFile(dllpath)
                                           .CreateInstance(jobRequest.JobFullClass);

                //第一種方式:
                var job = JobBuilder.Create(jobClassName.GetType()).StoreDurably(true)
                                          .WithIdentity(jobRequest.JobName, jobRequest.JobGroupName)
                                          .WithDescription(jobRequest.Description)
                                          .Build();
                
                scheduler.AddJob(job, true);

                //第二種方式:獲取job信息,再更新實體。。。
                var jobdetail = scheduler.GetJobDetail(new JobKey(jobRequest.JobName, jobRequest.JobGroupName));
添加job
//job暫停,全部關聯的trigger也必須暫停
                scheduler.PauseJob(new JobKey(jobName, groupName));
暫停job
 scheduler.ResumeJob(new JobKey(jobName, groupName));
恢復job

 2,trigger操做

 List<CronTriggerImpl> triggerList = new List<CronTriggerImpl>();

            //第一步:獲取全部的trigger信息
            var triggerKeys = scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup());

            foreach (var triggerkey in triggerKeys)
            {
                var triggerDetail = (CronTriggerImpl)scheduler.GetTrigger(triggerkey);

                triggerList.Add(triggerDetail);
            }

            var json = JsonConvert.SerializeObject(triggerList.Select(i => new
            {
                i.FullName,
                i.FullJobName,
                i.CronExpressionString,
                JobClassName = scheduler.GetJobDetail(i.JobKey).JobType.FullName,
                StartFireTime = i.StartTimeUtc.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                PrevFireTime = i.GetPreviousFireTimeUtc()?.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                NextFireTime = i.GetNextFireTimeUtc()?.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                TriggerStatus = scheduler.GetTriggerState(new TriggerKey(i.Name, i.Group)).ToString(),
                i.Priority,
                i.Description,
                i.Name,
                i.Group
            }));
查詢
 var exists = scheduler.CheckExists(new TriggerKey(triggerRequest.TriggerName,
                                                                 triggerRequest.TriggerGroupName));

                if (exists)
                {
                    return Json("已經存在同名的trigger,請更換!");
                }

                var forJobName = triggerRequest.ForJobName.Split('.');
                var trigger = TriggerBuilder.Create().ForJob(forJobName[1], forJobName[0])
                                            .WithIdentity(triggerRequest.TriggerName, triggerRequest.TriggerGroupName)
                                            .WithCronSchedule(triggerRequest.CronExpress)
                                            .WithDescription(triggerRequest.Description)
                                            .Build();

                scheduler.ScheduleJob(trigger);
添加
//暫停 「某一個trigger」
                scheduler.PauseTrigger(new TriggerKey(name, group));
暫停
//恢復 「某一個trigger」
                scheduler.ResumeTrigger(new TriggerKey(name, group));
恢復
scheduler.UnscheduleJob(new TriggerKey(name, group));
刪除
//編輯Trigger
                var forJobName = triggerRequest.ForJobName.Split('.');

                var trigger = TriggerBuilder.Create().ForJob(forJobName[1], forJobName[0])
                                            .WithIdentity(triggerRequest.TriggerName, triggerRequest.TriggerGroupName)
                                            .WithCronSchedule(triggerRequest.CronExpress)
                                            .WithDescription(triggerRequest.Description)
                                            .Build();

                //編輯trigger操做
                scheduler.RescheduleJob(new TriggerKey(triggerRequest.TriggerName, triggerRequest.TriggerGroupName), trigger);
編輯

3,scheduler操做

 var meta = scheduler.GetMetaData();
獲取元數據
  if (scheduler.InStandbyMode)
                {
                    //只有暫停的狀態,才能從新開啓
                    scheduler.Start();
                }
恢復
 if (scheduler.IsStarted)
                {
                    //暫停scheduler
                    scheduler.Standby();
                }
暫停
if (scheduler.IsStarted || scheduler.InStandbyMode)
                {
                    //暫停scheduler
                    scheduler.Shutdown();
                }
關閉

 4,整個demo

using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Matchers;
using Quartz.Impl.Triggers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Entitys;

namespace WebApplication1.Controllers
{
    [RoutePrefix("quartz")]
    public class QuartzController : Controller
    {
        static IScheduler scheduler = null;

        static QuartzController()
        {
            scheduler = StdSchedulerFactory.GetDefaultScheduler();
            scheduler.Start();
        }

        [Route("index")]
        public ActionResult Index()
        {
            return View();
        }

        //查詢job
        [Route("joblist")]
        public JsonResult JobList()
        {
            List<JobDetailImpl> jobList = new List<JobDetailImpl>();

            //第一步:獲取全部的job信息
            var jobKeySet = scheduler.GetJobKeys(GroupMatcher<JobKey>.AnyGroup());

            foreach (var jobKey in jobKeySet)
            {
                var jobDetail = (JobDetailImpl)scheduler.GetJobDetail(jobKey);

                jobList.Add(jobDetail);
            }

            var json = JsonConvert.SerializeObject(jobList.Select(i => new
            {
                i.Name,
                i.Group,
                i.Durable,
                i.JobDataMap,
                i.Description,
                TriggerList = string.Join(",", scheduler.GetTriggersOfJob(new JobKey(i.Name, i.Group))
                                    .Select(m => m.Key.ToString()))
            }));

            return Json(json);
        }

        //添加job
        [Route("addjob")]
        public JsonResult AddJob(JobRequestEntity jobRequest)
        {
            try
            {
                var exists = scheduler.CheckExists(new JobKey(jobRequest.JobName,
                                                              jobRequest.JobGroupName));

                if (exists && !jobRequest.IsEdit)
                {
                    return Json("已經存在同名的Job,請更換!");
                }

                var assemblyName = jobRequest.JobFullClass.Split('.')[0];
                var fullName = jobRequest.JobFullClass;
                var dllpath = Request.MapPath(string.Format("~/bin/{0}.dll", assemblyName));

                //須要執行的job名稱
                var jobClassName = Assembly.LoadFile(dllpath)
                                           .CreateInstance(jobRequest.JobFullClass);

                //第一種方式:
                var job = JobBuilder.Create(jobClassName.GetType()).StoreDurably(true)
                                          .WithIdentity(jobRequest.JobName, jobRequest.JobGroupName)
                                          .WithDescription(jobRequest.Description)
                                          .Build();
                
                scheduler.AddJob(job, true);

                //第二種方式:獲取job信息,再更新實體。。。
                var jobdetail = scheduler.GetJobDetail(new JobKey(jobRequest.JobName, jobRequest.JobGroupName));
                
                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //暫停job(可恢復)
        [Route("pausejob")]
        public JsonResult PauseJob(string jobName, string groupName)
        {
            try
            {
                //job暫停,全部關聯的trigger也必須暫停
                scheduler.PauseJob(new JobKey(jobName, groupName));

                return Json(1);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //恢復job
        [Route("resumejob")]
        public JsonResult ResumeJob(string jobName, string groupName)
        {
            try
            {
                scheduler.ResumeJob(new JobKey(jobName, groupName));

                return Json(1);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //刪除job
        [Route("removejob")]
        public JsonResult RemoveJob(string jobName, string groupName)
        {
            try
            {
                var isSuccess = scheduler.DeleteJob(new JobKey(jobName, groupName));

                return Json(isSuccess);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //trigger查詢
        [Route("triggerlist")]
        public JsonResult TriggerList()
        {
            List<CronTriggerImpl> triggerList = new List<CronTriggerImpl>();

            //第一步:獲取全部的trigger信息
            var triggerKeys = scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup());

            foreach (var triggerkey in triggerKeys)
            {
                var triggerDetail = (CronTriggerImpl)scheduler.GetTrigger(triggerkey);

                triggerList.Add(triggerDetail);
            }

            var json = JsonConvert.SerializeObject(triggerList.Select(i => new
            {
                i.FullName,
                i.FullJobName,
                i.CronExpressionString,
                JobClassName = scheduler.GetJobDetail(i.JobKey).JobType.FullName,
                StartFireTime = i.StartTimeUtc.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                PrevFireTime = i.GetPreviousFireTimeUtc()?.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                NextFireTime = i.GetNextFireTimeUtc()?.LocalDateTime.ToString("yyyy-MM-dd HH:mm:ss"),
                TriggerStatus = scheduler.GetTriggerState(new TriggerKey(i.Name, i.Group)).ToString(),
                i.Priority,
                i.Description,
                i.Name,
                i.Group
            }));

            return Json(json);
        }
        //添加trigger
        [Route("addtrigger")]
        public JsonResult AddTrigger(TriggerRequestEntity triggerRequest)
        {
            try
            {
                var exists = scheduler.CheckExists(new TriggerKey(triggerRequest.TriggerName,
                                                                 triggerRequest.TriggerGroupName));

                if (exists)
                {
                    return Json("已經存在同名的trigger,請更換!");
                }

                var forJobName = triggerRequest.ForJobName.Split('.');
                var trigger = TriggerBuilder.Create().ForJob(forJobName[1], forJobName[0])
                                            .WithIdentity(triggerRequest.TriggerName, triggerRequest.TriggerGroupName)
                                            .WithCronSchedule(triggerRequest.CronExpress)
                                            .WithDescription(triggerRequest.Description)
                                            .Build();

                scheduler.ScheduleJob(trigger);

                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //暫停trigger(可恢復)
        [Route("pausetrigger")]
        public JsonResult PauseTrigger(string name, string group)
        {
            try
            {
                //暫停 「某一個trigger」
                scheduler.PauseTrigger(new TriggerKey(name, group));

                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //恢復trigger
        [Route("resumetrigger")]
        public JsonResult ResumeTrigger(string name, string group)
        {
            try
            {
                //恢復 「某一個trigger」
                scheduler.ResumeTrigger(new TriggerKey(name, group));

                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //刪除trigger
        [Route("removetrigger")]
        public JsonResult RemoveTrigger(string name, string group)
        {
            try
            {
                scheduler.UnscheduleJob(new TriggerKey(name, group));

                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        //編輯trigger
        [Route("edittrigger")]
        public JsonResult EditTrigger(TriggerRequestEntity triggerRequest)
        {
            try
            {
                //編輯Trigger
                var forJobName = triggerRequest.ForJobName.Split('.');

                var trigger = TriggerBuilder.Create().ForJob(forJobName[1], forJobName[0])
                                            .WithIdentity(triggerRequest.TriggerName, triggerRequest.TriggerGroupName)
                                            .WithCronSchedule(triggerRequest.CronExpress)
                                            .WithDescription(triggerRequest.Description)
                                            .Build();

                //編輯trigger操做
                scheduler.RescheduleJob(new TriggerKey(triggerRequest.TriggerName, triggerRequest.TriggerGroupName), trigger);

                return Json("1");
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        //獲取scheduler元數據信息
        [Route("getmeta")]
        public JsonResult GetMeta()
        {
            try
            {
                var meta = scheduler.GetMetaData();

                var json = JsonConvert.SerializeObject(meta);

                return Json(json);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        /// <summary>
        /// 恢復scheduler
        /// </summary>
        /// <returns></returns>
        [Route("resumescheduler")]
        public JsonResult ResumeScheduler()
        {
            try
            {
                if (scheduler.InStandbyMode)
                {
                    //只有暫停的狀態,才能從新開啓
                    scheduler.Start();
                }

                return Json(1);
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        /// <summary>
        /// 暫停scheduler
        /// </summary>
        /// <returns></returns>
        [Route("pausescheduler")]
        public JsonResult PauseScheduler()
        {
            try
            {
                if (scheduler.IsStarted)
                {
                    //暫停scheduler
                    scheduler.Standby();
                }

                return Json(1);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        /// <summary>
        /// 關閉scheduler
        /// </summary>
        /// <returns></returns>
        [Route("shutdownscheduler")]
        public JsonResult ShutDownScheduler()
        {
            try
            {
                if (scheduler.IsStarted || scheduler.InStandbyMode)
                {
                    //暫停scheduler
                    scheduler.Shutdown();
                }

                return Json(1);
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}
demo

下載地址:https://pan.baidu.com/s/1uQMuQEvsky1poiBzg1H3JA

 

7、六大calendar排除

1,DailyCalendar
【適合在某一天的時間段上作「減法操做」】

 能夠動態的排除某天的某些時間段

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("daily")
                .WithCronSchedule("* * * * * ?").Build();

            //天天20點到21點不要執行
            var daily = new DailyCalendar(DateBuilder.DateOf(20, 0, 0).DateTime, DateBuilder.DateOf(21, 0, 0).DateTime);
            scheduler.AddCalendar("daily", daily, true, true);


            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
天天20點到21點不要執行

 

2,WeeklyCalendar
【適合以星期幾的維度上作「減法操做」】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("calendar")
                .WithCronSchedule("* * * * * ?").Build();

            //每週五不執行
            WeeklyCalendar calendar = new WeeklyCalendar();
            calendar.SetDayExcluded(DayOfWeek.Friday, true);
            scheduler.AddCalendar("calendar", calendar, true, true);

            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
每週五不執行

 

3,HolidayCalendar
【適合當年的某一天不能執行】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("calendar")
                .WithCronSchedule("* * * * * ?").Build();

            //指定某一天不能執行
            //6月16號不要執行
            var calendar = new HolidayCalendar();
            calendar.AddExcludedDate(DateTime.Now);
            scheduler.AddCalendar("calendar", calendar, true, true);

            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
6月16號不要執行

 

4,MonthlyCalendar
【適合某個月中的某一天不能執行】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("calendar")
                .WithCronSchedule("* * * * * ?").Build();

            //每個月20號不要執行
            var calendar = new MonthlyCalendar();
            calendar.SetDayExcluded(20, true);
            scheduler.AddCalendar("calendar", calendar, true, true);

            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
每個月20號不要執行

 

5,AnnualCalendar
【適合每一年指定的某一天不能執行】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("calendar")
                .WithCronSchedule("* * * * * ?").Build();

            //指定月份中的某一天不能執行
            var calendar = new AnnualCalendar();
            calendar.SetDayExcluded(DateTime.Now, true);
            scheduler.AddCalendar("calendar", calendar, true, true);

            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
指定月份中的某一天不能執行

 

6,CronCalendar
【字符串表達式來排除某一天,某一個月份,某一年均可以】

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Quartz;
using Quartz.Impl;
using Quartz.Listener;
using Quartz.Impl.Matchers;
using System.Threading;
using Quartz.Impl.Calendar;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("開始");

            //scheduler [10 +1 都開啓了,只不過都是等待狀態]
            var scheduler = StdSchedulerFactory.GetDefaultScheduler().Result;
            //[start 會讓 調度線程 啓動,從jobstore中獲取快要執行的trigger,而後獲取trigger關聯的job進行執行。]
            scheduler.Start();

            //job
            var job = JobBuilder.Create<JobTest>()
                .StoreDurably(true)
                .Build();
            scheduler.AddJob(job, true);

            //trigger 
            var trigger = TriggerBuilder.Create().ForJob(job)
                .ModifiedByCalendar("calendar")
                .WithCronSchedule("* * * * * ?").Build();

            //4月21號不要執行
            var calendar = new CronCalendar("* * * 21 4 ?");
            scheduler.AddCalendar("calendar", calendar, true, true);

            scheduler.ScheduleJob(trigger);

            Console.ReadLine();
        }
    }

    public class JobTest : IJob
    {
        private static int index = 0;
        public async Task Execute(IJobExecutionContext context)
        {
            index++;

            //記錄當前時間,記錄「scheduler」調度時間 ,記錄 下一次觸發時間
            Console.WriteLine("index={0}, current={1},schedulertime={2},nexttime={3}",
                                                                        index, DateTime.Now,
                                                                        context.ScheduledFireTimeUtc?.LocalDateTime,
                                                                        context.NextFireTimeUtc?.LocalDateTime);
        }
    }
}
4月21號不要執行
相關文章
相關標籤/搜索