前面寫了關於Quartz.NET開源作業調度框架的入門和Cron Trigger , 這次繼續這個系列, 這次想討論一下Quartz.NET中的Job如何通過執行上下文(Execution Contex)進行參數傳遞 , 有些參數想保存狀態該如何處理 . 在Quartz.NET中可以用JobDataMap進行參數傳遞.本例用Quartz.NET的任務來定期輪詢數據庫表,當數據庫的條目達到一定的數目后,進行預警.(其實可以將讀取的表和預警條件配置到數據庫中的預警條件表中,這樣就可以簡單實現一個自動預警提醒的小平台).
1 JobWithParametersExample
1 using System; 2 using System.Threading; 3
4 using Common.Logging; 5 using Quartz; 6 using Quartz.Impl; 7 using Quartz.Job; 8 using Quartz.Impl.Calendar; 9 using Quartz.Impl.Matchers; 10 namespace QuartzDemo 11 { 12
13 public class JobWithParametersExample 14 { 15 public string Name 16 { 17 get { return GetType().Name; } 18 } 19 private IScheduler sched = null; 20 public JobWithParametersExample(IScheduler _sched) 21 { 22 sched = _sched; 23 } 24 public virtual void Run() 25 { 26
27 //2S后執行
28 DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(null, 2); 29 IJobDetail job1 = JobBuilder.Create<JobWithParameters>() 30 .WithIdentity("job1", "group1") 31 .Build(); 32
33 ISimpleTrigger trigger1 = (ISimpleTrigger)TriggerBuilder.Create() 34 .WithIdentity("trigger1", "group1") 35 .StartAt(startTime) 36 .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).WithRepeatCount(100)) 37 .Build(); 38
39 // 設置初始參數
40 job1.JobDataMap.Put(JobWithParameters.tSQL, "SELECT * FROM [ACT_ID_USER]"); 41 job1.JobDataMap.Put(JobWithParameters.ExecutionCount, 1); 42
43 // 設置監聽器
44 JobListener listener = new JobListener(); 45 IMatcher<JobKey> matcher = KeyMatcher<JobKey>.KeyEquals(job1.Key); 46 sched.ListenerManager.AddJobListener(listener, matcher); 47
48 // 綁定trigger和job
49 sched.ScheduleJob(job1, trigger1); 50 //啟動
51 sched.Start(); 52
53 } 54 } 55 }
JobWithParametersExample用來配置job和trigger,同時定義了一個監聽器,來監聽定義的job.
2 JobWithParameters
1 using System; 2 using Common.Logging; 3 using Quartz; 4 using Quartz.Impl; 5 using Quartz.Job; 6 using System.Windows.Forms; 7 namespace QuartzDemo 8 { 9
10 [PersistJobDataAfterExecution] 11 [DisallowConcurrentExecution] 12 public class JobWithParameters : IJob 13 { 14
15 // 定義參數常量
16 public const string tSQL = "tSQL"; 17 public const string ExecutionCount = "count"; 18 public const string RowCount = "rowCount"; 19 public const string tableAlert = "tAlert"; 20 // Quartz 每次執行時都會重新實例化一個類, 因此Job類中的非靜態變量不能存儲狀態信息
21 private int counter = 1;//都為1 22 //private static int counter = 1;//可以保存狀態
23 public virtual void Execute(IJobExecutionContext context) 24 { 25
26 JobKey jobKey = context.JobDetail.Key; 27 // 獲取傳遞過來的參數
28 JobDataMap data = context.JobDetail.JobDataMap; 29 string SQL = data.GetString(tSQL); 30 int count = data.GetInt(ExecutionCount); 31
32 if (isOpen("FrmConsole")) 33 { 34 try
35 { 36 //獲取當前Form1實例
37 __instance = (FrmConsole)Application.OpenForms["FrmConsole"]; 38 //獲取當前執行的線程ID
39 __instance.SetInfo(jobKey + "Thread ID " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString()); 40 //數據庫操作
41 System.Data.DataTable tAlert = SqlHelper.getDateTable(SQL, null); 42 //回寫條數
43 data.Put(RowCount, tAlert.Rows.Count); 44 //通過方法更新消息
45 __instance.SetInfo(string.Format("{0} exec {1} = {2} get {3} rows\r\n execution count (from job map) is {4}\r\n execution count (from job member variable) is {5}", 46 jobKey, 47 tSQL, 48 SQL, 49 tAlert.Rows.Count, 50 count, counter)); 51 //怎么取出Datatable ? json to datatable 52 //data.Put(tableAlert, tAlert);
53 } 54 catch (Exception ex) 55 { 56 Console.WriteLine(ex.Message); 57 } 58 } 59 // 修改執行計數並回寫到job data map中
60 count++; 61 data.Put(ExecutionCount, count); 62 // 修改本地變量,如果是非靜態變量,不能存儲狀態
63 counter++; 64 } 65
66 private static FrmConsole __instance = null; 67
68 /// <summary>
69 /// 判斷窗體是否打開 70 /// </summary>
71 /// <param name="appName"></param>
72 /// <returns></returns>
73 private bool isOpen(string appName) 74 { 75 FormCollection collection = Application.OpenForms; 76 foreach (Form form in collection) 77 { 78 if (form.Name == appName) 79 { 80 return true; 81 } 82 } 83 return false; 84 } 85
86 } 87 }
Quartz 每次執行時都會重新實例化一個類, 因此Job類中的非靜態變量不能存儲狀態信息.如何要保存狀態信息可以用靜態變量進行處理,也可以用參數值進行傳入傳出來實現.
3 JobListener
1 using System; 2 using Common.Logging; 3 using Quartz; 4 using Quartz.Impl; 5 using Quartz.Job; 6 namespace QuartzDemo 7 { 8 public class JobListener : IJobListener 9 { 10
11 public virtual string Name 12 { 13 get { return "JobListener"; } 14 } 15
16 public virtual void JobToBeExecuted(IJobExecutionContext inContext) 17 { 18 //執行前執行
19 Console.WriteLine("JobToBeExecuted"); 20 } 21
22 public virtual void JobExecutionVetoed(IJobExecutionContext inContext) 23 { 24 //否決時執行
25 Console.WriteLine("JobExecutionVetoed"); 26 } 27
28 public virtual void JobWasExecuted(IJobExecutionContext inContext, JobExecutionException inException) 29 { 30 JobKey jobKey = inContext.JobDetail.Key; 31 // 獲取傳遞過來的參數
32 JobDataMap data = inContext.JobDetail.JobDataMap; 33 //獲取回傳的數據庫表條目數
34 int rowCount = data.GetInt(JobWithParameters.RowCount); 35
36 try
37 { 38 if (rowCount > 9) 39 { 40 inContext.Scheduler.PauseAll(); 41 System.Windows.Forms.MessageBox.Show("預警已超9條"); 42 inContext.Scheduler.ResumeAll(); 43
44 } 45 Console.WriteLine(rowCount.ToString()); 46 } 47 catch (SchedulerException e) 48 { 49
50 Console.Error.WriteLine(e.StackTrace); 51 } 52 } 53
54 } 55 }
4 效果