前面寫了關于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 QuartzDemo11 {12 13 public class JobWithParametersExample 14 {15 public string Name16 {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和job49 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 : IJob13 {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;//都為122 //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 try35 {36 //獲取當前Form1實例37 __instance = (FrmConsole)application.OpenForms["FrmConsole"];38 //獲取當前執行的線程ID39 __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 datatable52 //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 Name12 {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 try37 {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 }
新聞熱點
疑難解答