前面寫了關於Quartz.NET開源作業調度框架的入門和Cron Trigger , 這次繼續這個系列, 這次想討論一下Quartz.NET中的Job如何通過執行上下文(Execution Contex)進行參數傳遞 , 有些參數想保存狀態該如何處理 . 在Quartz.NET中可以用JobDataMap進行參數傳遞.本例用Quartz.NET的任務來定期輪詢數據庫表,當數據庫的條目達到一定的數目後,進行預警.(其實可以將讀取的表和預警條件配置到數據庫中的預警條件表中,這樣就可以簡單實現一個自動預警提醒的小平台).
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.
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類中的非靜態變量不能存儲狀態信息.如何要保存狀態信息可以用靜態變量進行處理,也可以用參數值進行傳入傳出來實現.
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 }

