一. 五大構件
引言: Quartz.Net的五大構件
1. 調度器:Scheduler
2. 作業任務:Job
3. 觸發器: Trigger
4. 線程池: SimpleThreadPool
5. 作業持久化:JobStore
二. Scheduler詳解
1. 創建Scheduler的兩種方式
(1). 直接通過StdSchedulerFactory類的GetDefaultScheduler方法創建
(2). 先創建StdSchedulerFactory,然后通過GetScheduler方法創建. 該方式可以在實體化StdSchedulerFactory的時候配置一些額外的信息,比如:配置SimpleThreadPool的個數、RemoteScheduler的遠程控制、數據庫的持久化等。(都在后續章節介紹)
2. Scheduler的簡單封裝
這里提供兩種思路,一種是單例的模式封裝,另一種是利用線程槽的模式封裝
(1). 單例模式:是指無論多少個用戶訪問,都只有一個實例,在web端上常用 (詳見:MySchedulerFactory類)
(2). 線程槽模式:是指單個用戶的單次鏈接,在未斷開連接之前,只有一個實例,下次重新連接,實例將重新創建(詳見:MySchedulerFactory2類)
代碼分享:
1 /// <summary> 2 /// 將Sheduler封裝成單例模式,解決多線程多用戶不唯一的問題 3 /// </summary> 4 public class MySchedulerFactory 5 { 6 /// <summary> 7 /// 靜態變量:由CLR保證,在程序第一次使用該類之前被調用,而且只調用一次 8 /// </summary> 9 private static IScheduler _Scheduler = StdSchedulerFactory.GetDefaultScheduler(); 10 public static IScheduler CreateScheduler() 11 { 12 return _Scheduler; 13 } 14 } 15 /// <summary> 16 /// 通過線程槽進行一個優化 17 /// </summary> 18 public class MySchedulerFactory2 19 { 20 public static IScheduler CreateScheduler() 21 { 22 IScheduler scheduler = CallContext.GetData(typeof(MySchedulerFactory2).Name) as IScheduler; 23 if (scheduler == null) 24 { 25 scheduler = StdSchedulerFactory.GetDefaultScheduler(); 26 CallContext.SetData(typeof(MySchedulerFactory2).Name, scheduler); 27 } 28 return scheduler; 29 } 30 }
3. Scheduler的基本方法:
(1). 開啟:Start
(2). 關閉:ShutDown
(3). 暫停job或Trigger:PauseAll、PauseJob、PauseJobs、PauseTrigger、PauseTriggers
(4). 恢復job或Trigger:ResumeAll、ResumeJob、ResumeJobs、ResumeTrigger、ResumeTriggers
(5). 將job和trigger加入Scheduler中:ScheduleJob
(6). 添加Job:AddJob
PS:更多方法以及如何封裝使用,將在后面的框架章節介紹
分享一段完成的代碼:

1 public static void SchedulerShow() 2 { 3 //1.創建Scheduler有兩種方式 4 //方式一:直接通過StdSchedulerFactory類的GetDefaultScheduler方法創建 5 IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler(); 6 //方式二:先創建StdSchedulerFactory,然后通過GetScheduler方法創建 7 var factory = new StdSchedulerFactory(); 8 IScheduler scheduler2 = factory.GetScheduler(); 9 10 //2.創建一個具體的作業即job (具體的job需要單獨在一個文件中執行) 11 var job = JobBuilder.Create<HelloJob>().Build(); 12 13 //3.創建並配置一個觸發器即trigger 1s執行一次 14 var trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(1) 15 .RepeatForever()).Build(); 16 //4.將job和trigger加入到作業調度池中 17 scheduler.ScheduleJob(job, trigger); 18 19 //5.開啟調度 20 scheduler.Start(); 21 }
三. Job詳解
1. 幾個類型
①. JobBuilder:用來創建JobDetail。
②. IJob:具體作業任務需要實現該接口,並實現里面的方法
③. IJobDetail:用來定義工作實例
2. job的創建有兩種形式:
①.Create的泛型方式:寫起來代碼簡潔方便。
②.反射+OfType的方式:用於后期動態綁定,通過程序集的反射
1 //1 (Create的泛型方式) 2 IJobDetail job1 = JobBuilder.Create<HelloJob2>() 3 .UsingJobData("name", "ypf") 4 .UsingJobData("age", "12") 5 .WithIdentity("job1", "myJob1") 6 .WithDescription("我是用來對該job進行描述的") 7 .StoreDurably(true) 8 .Build(); 9 10 //2 (反射+OfType的方式) 11 //通過反射來創建類 12 var type = Assembly.Load("QuartzDemo").CreateInstance("QuartzDemo.HelloJob2"); 13 //OfType的方式加載類型 14 IJobDetail job2 = JobBuilder.Create().OfType(type.GetType()) 15 .UsingJobData("name", "ypf") 16 .UsingJobData("age", "12") 17 .StoreDurably(true) 18 .Build();
3.常用的幾個方法
①.UsingJobData:給Job添加一些附加值,存儲在JobDataMap里,可以在具體的Job中獲取。(通過context.JobDetail.JobDataMap獲取)
②.StoreDurably:讓該job持久化,不被銷毀.(默認情況下為false,即job沒有對應的trigger的話,job就被銷毀)
③.WithIdentity:身份標記,給job起個名稱,便於和Trigger關聯的時候使用.
④.WithDescription:用來對job進行描述,並沒有什么實際作用
分享完整代碼:
/// <summary> /// Job詳解 /// </summary> public static void JobShow() { //1. 創建Schedule IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler(); //2. 創建Job //2.1 (Create的泛型方式) IJobDetail job1 = JobBuilder.Create<HelloJob2>() .UsingJobData("name", "ypf") .UsingJobData("age", "12") .WithIdentity("job1", "myJob1") .WithDescription("我是用來對該job進行描述的") .StoreDurably(true) .Build(); //2.2 (反射+OfType的方式) //通過反射來創建類 var type = Assembly.Load("QuartzDemo").CreateInstance("QuartzDemo.HelloJob2"); //OfType的方式加載類型 IJobDetail job2 = JobBuilder.Create().OfType(type.GetType()) .UsingJobData("name", "ypf") .UsingJobData("age", "12") .StoreDurably(true) .Build(); IJobDetail job3 = JobBuilder.Create(type.GetType()) .UsingJobData("name", "ypf") .UsingJobData("age", "12") .StoreDurably(true) .Build(); //3. 創建Trigger ITrigger trigger = TriggerBuilder.Create().WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever()).Build(); //4. 將Job和Trigger加入調度器中 //scheduler.ScheduleJob(job1, trigger); //scheduler.ScheduleJob(job2, trigger); scheduler.ScheduleJob(job3, trigger); //5. 開始調度 scheduler.Start(); } /// <summary> /// 實現IJob接口 /// </summary> class HelloJob2 : IJob { void IJob.Execute(IJobExecutionContext context) { var name = context.JobDetail.JobDataMap["name"]; var age = context.JobDetail.JobDataMap["age"]; Console.WriteLine("name值為:{0},age值為:{1}", name, age); } }
運行結果:
4. Job和觸發器關聯的形式:1對1、1對多、多對1
(PS:在下面Trigger處詳細介紹)