你的位置:首页 > ASP.net教程

[ASP.net教程]Quartz.NET开源作业调度框架系列(三):IJobExecutionContext 参数传递


  前面写了关于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 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.

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 : 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类中的非静态变量不能存储状态信息.如何要保存状态信息可以用静态变量进行处理,也可以用参数值进行传入传出来实现.

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 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 }

4 效果