zoukankan      html  css  js  c++  java
  • Quartz.Net初探

         想必大家在工作中经常会遇到这样类似的需求,在某个时间或者需要不间断的执行某个业务动作去满足任务需求。例如,我们写了一个job,定时去处理一些任务,在没有了解到Quartz.Net之前,我是这样做的,进行轮询处理,如图:

     

    是不是感觉很low啊。前些日子,了解到了Quartz.Net,它是一个强大的开源任务调度器,它提供的触发器以及Cron表达式能够很好的满足我们在日常开发中遇到的定时服务的工作处理,为了在以后工作中更好的使用它,我对它的基本使用方法进行了整理,当然下面所讲到的只是它的一些常用功能,至于更强大的功能,例如远程调度等等,还需要后续再进一步了解。但是在我看来,已能够满足我们在日常中的大部分开发工作。

    1、建立如下解决方案,如图

     

    正如大家看到的,我在解决方案中添加了QuartzTest的控制台项目进行demo演示,需要说明的是,大家可通过Nuget将Quartz包添加至项目当中。根据Quartz的常用操作,整理出了 BaseJob以及QuartzHelper帮助类。

    BaseJob类中包含了要执行任务的基本信息,例如Job名称,组名,触发器名称,执行间隔时间等等信息,在实现具体Job时,只要继承该基类并使用相应的构造函数对Job基本信息进行初始化即可。

    如下图:

    QuartzHelper中对常用的任务调度方法进行了整理,这里我们将TestJob添加至调度器并开始任务的执行,如下图:

    该Demo以及整理的完整代码如下:

      1  /// <summary>
      2     /// 任务基类
      3     /// </summary>
      4     public abstract class BaseJob : IJob
      5     {
      6         private string _jobName = string.Empty;
      7         private string _gropName = string.Empty;
      8         private string _triggerName = string.Empty;
      9         private int _intervalTime;
     10         private DateTimeOffset _startTime;
     11         private DateTimeOffset? _endTime;
     12         private int _repeatCount;
     13         private string _cronExpression;
     14 
     15 
     16         /// <summary>
     17         /// 无参构造函数
     18         /// </summary>
     19         public BaseJob()
     20         {
     21 
     22         }
     23       
     24 
     25         /// <summary>
     26         /// 构造函数
     27         /// </summary>
     28         /// <param name="jobName">任务名称</param>
     29         /// <param name="triggerName">触发器名称</param>
     30         /// <param name="gropName">任务组名称</param>
     31         /// <param name="intervalTime">间隔时间</param>
     32         public BaseJob(string jobName, string triggerName, string gropName, int intervalTime)
     33         {
     34             this._jobName = jobName;
     35             this._triggerName = triggerName;
     36             this._gropName = gropName;
     37             this._intervalTime = intervalTime;
     38         }
     39 
     40 
     41         /// <summary>
     42         /// 构造函数
     43         /// </summary>
     44         /// <param name="jobName">任务名称</param>
     45         /// <param name="triggerName">触发器名称</param>
     46         /// <param name="gropName">任务组名称</param>
     47         /// <param name="intervalTime">间隔时间</param>
     48         /// <param name="cronExpression">cron表达式</param>
     49         public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, string cronExpression)
     50         {
     51             this._jobName = jobName;
     52             this._triggerName = triggerName;
     53             this._gropName = gropName;
     54             this._intervalTime = intervalTime;
     55             this._cronExpression = cronExpression;
     56         }
     57 
     58 
     59         /// <summary>
     60         /// 构造函数
     61         /// </summary>
     62         /// <param name="jobName">任务名称</param>
     63         /// <param name="triggerName">触发器名称</param>
     64         /// <param name="gropName">任务组名称</param>
     65         /// <param name="intervalTime">间隔时间</param>
     66         /// <param name="startTime">开始时间</param>
     67         /// <param name="endTime">结束时间</param>
     68         public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, DateTimeOffset startTime, DateTimeOffset? endTime)
     69         {
     70             this._jobName = jobName;
     71             this._triggerName = triggerName;
     72             this._gropName = gropName;
     73             this._intervalTime = intervalTime;
     74             this._startTime = startTime;
     75             this._endTime = endTime;
     76         }
     77 
     78 
     79         /// <summary>
     80         /// 构造函数
     81         /// </summary>
     82         /// <param name="jobName">任务名称</param>
     83         /// <param name="triggerName">触发器名称</param>
     84         /// <param name="gropName">任务组名称</param>
     85         /// <param name="intervalTime">间隔时间</param>
     86         /// <param name="startTime">开始时间</param>
     87         /// <param name="endTime">结束时间</param>
     88         /// <param name="repeatCount">重复次数</param>
     89         public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, DateTimeOffset startTime, DateTimeOffset? endTime, int repeatCount)
     90         {
     91             this._jobName = jobName;
     92             this._triggerName = triggerName;
     93             this._gropName = gropName;
     94             this._intervalTime = intervalTime;
     95             this._startTime = startTime;
     96             this._endTime = endTime;
     97             this._repeatCount = repeatCount;
     98         }
     99 
    100 
    101 
    102         /// <summary>
    103         /// 任务名称
    104         /// </summary>
    105         public string JobName
    106         {
    107             get { return _jobName; }
    108             set { _jobName = value; }
    109         }
    110 
    111         /// <summary>
    112         /// 触发器名称
    113         /// </summary>
    114         public string TriggerName
    115         {
    116             get { return _triggerName; }
    117             set { _triggerName = value; }
    118         }
    119 
    120         /// <summary>
    121         /// 任务组名称
    122         /// </summary>
    123         public string GropName
    124         {
    125             get { return _gropName; }
    126             set { _gropName = value; }
    127         }
    128 
    129         /// <summary>
    130         /// 执行间隔时间
    131         /// </summary>
    132         public int IntervalTime
    133         {
    134             get { return _intervalTime; }
    135             set { _intervalTime = value; }
    136         }
    137 
    138         /// <summary>
    139         /// 开始时间
    140         /// </summary>
    141         public DateTimeOffset StartTime
    142         {
    143             get { return _startTime; }
    144             set
    145             {
    146                 if (value == null || value == DateTime.MinValue) _startTime = SystemTime.UtcNow();
    147                 else _startTime = value;
    148             }
    149         }
    150 
    151         /// <summary>
    152         /// 结束时间
    153         /// </summary>
    154         public DateTimeOffset? EndTime
    155         {
    156             get { return _endTime; }
    157             set { _endTime = value; }
    158         }
    159 
    160         /// <summary>
    161         /// 重复执行次数
    162         /// </summary>
    163         public int RepeatCount
    164         {
    165             get { return _repeatCount; }
    166             set { _repeatCount = value; }
    167         }
    168 
    169         /// <summary>
    170         /// Cron表达式
    171         /// </summary>
    172         public string CronExpression
    173         {
    174             get { return _cronExpression; }
    175             set { _cronExpression = value; }
    176         }
    177 
    178 
    179         /// <summary>
    180         /// 任务执行
    181         /// </summary>
    182         /// <param name="context">任务执行上下文</param>
    183         public abstract void Execute(IJobExecutionContext context);
    184     }

       

      1  /// <summary>
      2     /// Quartz帮助类
      3     /// </summary>
      4     public class QuartzHelper
      5     {
      6         private static ISchedulerFactory _schedulerFactory;
      7         private static IScheduler _scheduler;
      8 
      9         /// <summary>
     10         /// 构造函数
     11         /// </summary>
     12         static QuartzHelper()
     13         {
     14             _schedulerFactory = CreateSchedulerFactory();
     15             _scheduler = GetScheduler();
     16         }
     17 
     18         #region 获取服务器使用的调度程序
     19         /// <summary>
     20         /// 获取服务器使用的调度程序。
     21         /// </summary>
     22         /// <returns></returns>
     23         protected static IScheduler GetScheduler()
     24         {
     25             return _schedulerFactory.GetScheduler();
     26         }
     27         #endregion
     28 
     29         #region 创建调度器工厂
     30         /// <summary>
     31         /// 创建调度器工厂。
     32         /// </summary>
     33         /// <returns></returns>
     34         protected static ISchedulerFactory CreateSchedulerFactory()
     35         {
     36             return new StdSchedulerFactory();
     37         }
     38         #endregion
     39 
     40         #region 委托调度器,启动实例
     41         /// <summary>
     42         /// 委托调度器,启动实例。
     43         /// </summary>
     44         public static void Start()
     45         {
     46             try
     47             {
     48                 _scheduler.Start();
     49             }
     50             catch (Exception ex)
     51             {
     52                 throw ex;
     53             }
     54         }
     55         #endregion
     56 
     57         #region 委托调度器,停止实例
     58         /// <summary>
     59         ///  委托调度器,停止实例。
     60         /// </summary>
     61         public static void Stop()
     62         {
     63             try
     64             {
     65                 if (!_scheduler.IsShutdown)
     66                     _scheduler.Shutdown(true);
     67             }
     68             catch (Exception ex)
     69             {
     70                 throw ex;
     71             }
     72         }
     73         #endregion
     74 
     75         #region 暂停调度器中所有的活动
     76         /// <summary>
     77         /// 暂停调度器中所有的活动。
     78         /// </summary>
     79         public static void Pause()
     80         {
     81             try
     82             {
     83                 _scheduler.PauseAll();
     84             }
     85             catch (Exception ex)
     86             {
     87                 throw ex;
     88             }
     89         }
     90         #endregion
     91 
     92         #region 恢复所有活动
     93         /// <summary>
     94         /// 恢复所有活动。
     95         /// </summary>
     96         public static void Resume()
     97         {
     98             try
     99             {
    100                 _scheduler.ResumeAll();
    101             }
    102             catch (Exception ex)
    103             {
    104                 throw ex;
    105             }
    106         }
    107         #endregion
    108 
    109         #region 添加任务(任务间隔时间单位:小时)
    110         /// <summary>
    111         /// 添加任务(任务间隔时间单位:小时)
    112         /// </summary>
    113         /// <typeparam name="T">具体任务</typeparam>
    114         public static void AddJobForHours<T>()
    115              where T : BaseJob, new()
    116         {
    117             try
    118             {
    119                 T job = new T();
    120                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    121                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
    122                                                               .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
    123                                                               .Build();
    124                 _scheduler.ScheduleJob(jobDetail, trigger);
    125             }
    126             catch (Exception ex)
    127             {
    128                 throw ex;
    129             }
    130         }
    131         #endregion
    132 
    133         #region  添加任务(任务间隔时间单位:分钟)
    134         /// <summary>
    135         /// 添加任务(任务间隔时间单位:分钟)
    136         /// </summary>
    137         /// <typeparam name="T">具体任务</typeparam>
    138         public static void AddJobForMinutes<T>()
    139               where T : BaseJob, new()
    140         {
    141             try
    142             {
    143                 T job = new T();
    144                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    145                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
    146                                                               .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
    147                                                               .Build();
    148                 _scheduler.ScheduleJob(jobDetail, trigger);
    149             }
    150             catch (Exception ex)
    151             {
    152                 throw ex;
    153             }
    154         }
    155         #endregion
    156 
    157         #region 添加任务(任务间隔时间单位:秒)
    158         /// <summary>
    159         /// 添加任务(任务间隔时间单位:秒)
    160         /// </summary>
    161         /// <typeparam name="T">具体任务</typeparam>
    162         public static void AddJobForSeconds<T>()
    163              where T : BaseJob, new()
    164         {
    165             try
    166             {
    167                 T job = new T();
    168                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    169                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
    170                                                               .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
    171                                                               .Build();
    172                 _scheduler.ScheduleJob(jobDetail, trigger);
    173             }
    174             catch (Exception ex)
    175             {
    176                 throw ex;
    177             }
    178         }
    179         #endregion
    180 
    181         #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:小时)
    182         /// <summary>
    183         /// 根据开始以及结束时间进行添加任务(任务间隔时间单位:小时)
    184         /// </summary>
    185         /// <typeparam name="T">具体任务</typeparam>
    186         public static void AddJobForHoursStartEndTime<T>()
    187              where T : BaseJob, new()
    188         {
    189             try
    190             {
    191                 T job = new T();
    192                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    193                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    194                                                               .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
    195                                                               .Build();
    196                 _scheduler.ScheduleJob(jobDetail, trigger);
    197             }
    198             catch (Exception ex)
    199             {
    200                 throw ex;
    201             }
    202         }
    203         #endregion
    204 
    205         #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:分钟)
    206         /// <summary>
    207         /// 根据开始以及结束时间进行添加任务(任务间隔时间单位:分钟)
    208         /// </summary>
    209         /// <typeparam name="T">具体任务</typeparam>
    210         public static void AddJobForMinutesStartEndTime<T>()
    211               where T : BaseJob, new()
    212         {
    213             try
    214             {
    215                 T job = new T();
    216                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    217                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    218                                                               .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
    219                                                               .Build();
    220                 _scheduler.ScheduleJob(jobDetail, trigger);
    221             }
    222             catch (Exception ex)
    223             {
    224                 throw ex;
    225             }
    226         }
    227         #endregion
    228 
    229         #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:秒)
    230         /// <summary>
    231         /// 根据开始以及结束时间添加任务(任务间隔时间单位:秒)
    232         /// </summary>
    233         /// <typeparam name="T">具体任务</typeparam>
    234         public static void AddJobForSecondsStartEndTime<T>()
    235              where T : BaseJob, new()
    236         {
    237             try
    238             {
    239                 T job = new T();
    240                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    241                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    242                                                               .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
    243                                                               .Build();
    244                 _scheduler.ScheduleJob(jobDetail, trigger);
    245             }
    246             catch (Exception ex)
    247             {
    248                 throw ex;
    249             }
    250         }
    251         #endregion
    252 
    253         #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:小时)
    254         /// <summary>
    255         /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:小时)
    256         /// </summary>
    257         /// <typeparam name="T">具体任务</typeparam>
    258         public static void AddJobForHoursRepeatCount<T>()
    259              where T : BaseJob, new()
    260         {
    261             try
    262             {
    263                 T job = new T();
    264                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    265                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    266                                                               .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).WithRepeatCount(job.RepeatCount))
    267                                                               .Build();
    268                 _scheduler.ScheduleJob(jobDetail, trigger);
    269             }
    270             catch (Exception ex)
    271             {
    272                 throw ex;
    273             }
    274         }
    275         #endregion
    276 
    277         #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:分钟)
    278         /// <summary>
    279         /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:分钟)
    280         /// </summary>
    281         /// <typeparam name="T">具体任务</typeparam>
    282         public static void AddJobForMinutesRepeatCount<T>()
    283               where T : BaseJob, new()
    284         {
    285             try
    286             {
    287                 T job = new T();
    288                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    289                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    290                                                               .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).WithRepeatCount(job.RepeatCount))
    291                                                               .Build();
    292                 _scheduler.ScheduleJob(jobDetail, trigger);
    293             }
    294             catch (Exception ex)
    295             {
    296                 throw ex;
    297             }
    298         }
    299         #endregion
    300 
    301         #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:秒)
    302         /// <summary>
    303         /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:秒)
    304         /// </summary>
    305         /// <typeparam name="T">具体任务</typeparam>
    306         public static void AddJobForSecondsRepeatCount<T>()
    307              where T : BaseJob, new()
    308         {
    309             try
    310             {
    311                 T job = new T();
    312                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    313                 ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
    314                                                               .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).WithRepeatCount(job.RepeatCount))
    315                                                               .Build();
    316                 _scheduler.ScheduleJob(jobDetail, trigger);
    317             }
    318             catch (Exception ex)
    319             {
    320                 throw ex;
    321             }
    322         }
    323         #endregion
    324 
    325         #region 通过Cron表达式添加任务
    326         /// <summary>
    327         /// 通过Cron表达式添加任务
    328         /// </summary>
    329         /// <typeparam name="T">具体任务</typeparam>
    330         public static void AddJobForCron<T>()
    331             where T : BaseJob, new()
    332         {
    333             try
    334             {
    335                 T job = new T();
    336                 IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
    337 
    338                 ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
    339                                              .WithIdentity(job.TriggerName, job.GropName)
    340                                              .WithCronSchedule(job.CronExpression)
    341                                              .Build();
    342                 _scheduler.ScheduleJob(jobDetail, trigger);
    343             }
    344             catch (Exception ex)
    345             {
    346                 throw ex;
    347             }
    348         }
    349         #endregion
    350     }
     1   /// <summary>
     2     /// 测试 job
     3     /// </summary>
     4     public class TestJob : BaseJob
     5     {
     6         public TestJob() : base("TestJob", "TestTrigger", "TestGrop",1) { }
     7         public override void Execute(IJobExecutionContext context)
     8         {
     9             try
    10             {
    11                 Console.WriteLine(string.Format("当前任务执行时间:{0}", DateTime.Now.ToString()));
    12                 Thread.Sleep(TimeSpan.FromSeconds(3));
    13             }
    14             catch (Exception ex)
    15             {
    16                 throw ex;
    17             }
    18         }
    19     }
      class Program
        {
            static void Main(string[] args)
            {
                QuartzHelper.AddJobForSeconds<TestJob>();
                QuartzHelper.Start();
            }
        }

    2、运行解决方案,得到如下结果

     发现是不是任务按照我们所希望的那样运行了,但是大家有没有注意到,TestJob中 有这样一句代码:  Thread.Sleep(TimeSpan.FromSeconds(3));

    任务是Sleep3秒钟的,可是我们的Job却一直在执行呢,即使上一次任务还没执行完,它又开始执行了。在我们的实际开发中,我们需要一次任务执行完成后再执行下一次任务。
    我们对TestJob 进行改造,代码如下:
     1   /// <summary>
     2     /// 测试 job
     3     /// </summary>
     4     [DisallowConcurrentExecution]
     5     public class TestJob : BaseJob
     6     {
     7         public TestJob() : base("TestJob", "TestTrigger", "TestGrop",1) { }
     8         public override void Execute(IJobExecutionContext context)
     9         {
    10             try
    11             {
    12                 Console.WriteLine(string.Format("当前任务执行时间:{0}", DateTime.Now.ToString()));
    13                 Thread.Sleep(TimeSpan.FromSeconds(3));
    14             }
    15             catch (Exception ex)
    16             {
    17                 throw ex;
    18             }
    19         }
    20     }

    再次运行,如图:

    大家发现区别没呢,没错,我们在TestJob类上添加了“DisallowConcurrentExecution”特性,这样,就能在一次任务执行完成后,再进行下次任务的执行了。



    勤勤恳恳工作,踏踏实实生活
  • 相关阅读:
    Vue.js整理
    linux~dd命令
    linux 开机自启动的两种方式
    解决mount.nfs: access denied by server while mounting
    pip与apt-get的使用
    Mysql 中字符串的截取
    学生练习:括号匹配
    迷宫问题,打印所有路径,深度搜索,dfs
    vector用法
    【CF1257A】Two Rival Students【思维】
  • 原文地址:https://www.cnblogs.com/kangkey/p/6941245.html
Copyright © 2011-2022 走看看