Quartz.Net初探
想必大家在工作中经常会遇到这样类似的需求,在某个时间或者需要不间断的执行某个业务动作去满足任务需求。例如,我们写了一个job,定时去处理一些任务,在没有了解到Quartz.Net之前,我是这样做的,进行轮询处理,如图:
是不是感觉很low啊。前些日子,了解到了Quartz.Net,它是一个强大的开源任务调度器,它提供的触发器以及Cron表达式能够很好的满足我们在日常开发中遇到的定时服务的工作处理,为了在以后工作中更好的使用它,我对它的基本使用方法进行了整理,当然下面所讲到的只是它的一些常用功能,至于更强大的功能,例如远程调度等等,还需要后续再进一步了解。但是在我看来,已能够满足我们在日常中的大部分开发工作。
1、建立如下解决方案,如图:
正如大家看到的,我在解决方案中添加了QuartzTest的控制台项目进行demo演示,需要说明的是,大家可通过Nuget将Quartz包添加至项目当中。根据Quartz的常用操作,整理出了 BaseJob以及QuartzHelper帮助类。
BaseJob类中包含了要执行任务的基本信息,例如Job名称,组名,触发器名称,执行间隔时间等等信息,在实现具体Job时,只要继承该基类并使用相应的构造函数对Job基本信息进行初始化即可。
如下图:
QuartzHelper中对常用的任务调度方法进行了整理,这里我们将TestJob添加至调度器并开始任务的执行,如下图:
该Demo以及整理的完整代码如下:
- /// <summary>
- /// 任务基类
- /// </summary>
- public abstract class BaseJob : IJob
- {
- private string _jobName = string.Empty;
- private string _gropName = string.Empty;
- private string _triggerName = string.Empty;
- private int _intervalTime;
- private DateTimeOffset _startTime;
- private DateTimeOffset? _endTime;
- private int _repeatCount;
- private string _cronExpression;
- /// <summary>
- /// 无参构造函数
- /// </summary>
- public BaseJob()
- {
- }
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="jobName">任务名称</param>
- /// <param name="triggerName">触发器名称</param>
- /// <param name="gropName">任务组名称</param>
- /// <param name="intervalTime">间隔时间</param>
- public BaseJob(string jobName, string triggerName, string gropName, int intervalTime)
- {
- this._jobName = jobName;
- this._triggerName = triggerName;
- this._gropName = gropName;
- this._intervalTime = intervalTime;
- }
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="jobName">任务名称</param>
- /// <param name="triggerName">触发器名称</param>
- /// <param name="gropName">任务组名称</param>
- /// <param name="intervalTime">间隔时间</param>
- /// <param name="cronExpression">cron表达式</param>
- public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, string cronExpression)
- {
- this._jobName = jobName;
- this._triggerName = triggerName;
- this._gropName = gropName;
- this._intervalTime = intervalTime;
- this._cronExpression = cronExpression;
- }
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="jobName">任务名称</param>
- /// <param name="triggerName">触发器名称</param>
- /// <param name="gropName">任务组名称</param>
- /// <param name="intervalTime">间隔时间</param>
- /// <param name="startTime">开始时间</param>
- /// <param name="endTime">结束时间</param>
- public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, DateTimeOffset startTime, DateTimeOffset? endTime)
- {
- this._jobName = jobName;
- this._triggerName = triggerName;
- this._gropName = gropName;
- this._intervalTime = intervalTime;
- this._startTime = startTime;
- this._endTime = endTime;
- }
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="jobName">任务名称</param>
- /// <param name="triggerName">触发器名称</param>
- /// <param name="gropName">任务组名称</param>
- /// <param name="intervalTime">间隔时间</param>
- /// <param name="startTime">开始时间</param>
- /// <param name="endTime">结束时间</param>
- /// <param name="repeatCount">重复次数</param>
- public BaseJob(string jobName, string triggerName, string gropName, int intervalTime, DateTimeOffset startTime, DateTimeOffset? endTime, int repeatCount)
- {
- this._jobName = jobName;
- this._triggerName = triggerName;
- this._gropName = gropName;
- this._intervalTime = intervalTime;
- this._startTime = startTime;
- this._endTime = endTime;
- this._repeatCount = repeatCount;
- }
- /// <summary>
- /// 任务名称
- /// </summary>
- public string JobName
- {
- get { return _jobName; }
- set { _jobName = value; }
- }
- /// <summary>
- /// 触发器名称
- /// </summary>
- public string TriggerName
- {
- get { return _triggerName; }
- set { _triggerName = value; }
- }
- /// <summary>
- /// 任务组名称
- /// </summary>
- public string GropName
- {
- get { return _gropName; }
- set { _gropName = value; }
- }
- /// <summary>
- /// 执行间隔时间
- /// </summary>
- public int IntervalTime
- {
- get { return _intervalTime; }
- set { _intervalTime = value; }
- }
- /// <summary>
- /// 开始时间
- /// </summary>
- public DateTimeOffset StartTime
- {
- get { return _startTime; }
- set
- {
- if (value == null || value == DateTime.MinValue) _startTime = SystemTime.UtcNow();
- else _startTime = value;
- }
- }
- /// <summary>
- /// 结束时间
- /// </summary>
- public DateTimeOffset? EndTime
- {
- get { return _endTime; }
- set { _endTime = value; }
- }
- /// <summary>
- /// 重复执行次数
- /// </summary>
- public int RepeatCount
- {
- get { return _repeatCount; }
- set { _repeatCount = value; }
- }
- /// <summary>
- /// Cron表达式
- /// </summary>
- public string CronExpression
- {
- get { return _cronExpression; }
- set { _cronExpression = value; }
- }
- /// <summary>
- /// 任务执行
- /// </summary>
- /// <param name="context">任务执行上下文</param>
- public abstract void Execute(IJobExecutionContext context);
- }
- /// <summary>
- /// Quartz帮助类
- /// </summary>
- public class QuartzHelper
- {
- private static ISchedulerFactory _schedulerFactory;
- private static IScheduler _scheduler;
- /// <summary>
- /// 构造函数
- /// </summary>
- static QuartzHelper()
- {
- _schedulerFactory = CreateSchedulerFactory();
- _scheduler = GetScheduler();
- }
- #region 获取服务器使用的调度程序
- /// <summary>
- /// 获取服务器使用的调度程序。
- /// </summary>
- /// <returns></returns>
- protected static IScheduler GetScheduler()
- {
- return _schedulerFactory.GetScheduler();
- }
- #endregion
- #region 创建调度器工厂
- /// <summary>
- /// 创建调度器工厂。
- /// </summary>
- /// <returns></returns>
- protected static ISchedulerFactory CreateSchedulerFactory()
- {
- return new StdSchedulerFactory();
- }
- #endregion
- #region 委托调度器,启动实例
- /// <summary>
- /// 委托调度器,启动实例。
- /// </summary>
- public static void Start()
- {
- try
- {
- _scheduler.Start();
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 委托调度器,停止实例
- /// <summary>
- /// 委托调度器,停止实例。
- /// </summary>
- public static void Stop()
- {
- try
- {
- if (!_scheduler.IsShutdown)
- _scheduler.Shutdown(true);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 暂停调度器中所有的活动
- /// <summary>
- /// 暂停调度器中所有的活动。
- /// </summary>
- public static void Pause()
- {
- try
- {
- _scheduler.PauseAll();
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 恢复所有活动
- /// <summary>
- /// 恢复所有活动。
- /// </summary>
- public static void Resume()
- {
- try
- {
- _scheduler.ResumeAll();
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 添加任务(任务间隔时间单位:小时)
- /// <summary>
- /// 添加任务(任务间隔时间单位:小时)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForHours<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
- .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 添加任务(任务间隔时间单位:分钟)
- /// <summary>
- /// 添加任务(任务间隔时间单位:分钟)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForMinutes<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
- .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 添加任务(任务间隔时间单位:秒)
- /// <summary>
- /// 添加任务(任务间隔时间单位:秒)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForSeconds<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartNow()
- .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:小时)
- /// <summary>
- /// 根据开始以及结束时间进行添加任务(任务间隔时间单位:小时)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForHoursStartEndTime<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:分钟)
- /// <summary>
- /// 根据开始以及结束时间进行添加任务(任务间隔时间单位:分钟)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForMinutesStartEndTime<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间进行添加任务(任务间隔时间单位:秒)
- /// <summary>
- /// 根据开始以及结束时间添加任务(任务间隔时间单位:秒)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForSecondsStartEndTime<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).RepeatForever())
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:小时)
- /// <summary>
- /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:小时)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForHoursRepeatCount<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInHours(job.IntervalTime).WithRepeatCount(job.RepeatCount))
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:分钟)
- /// <summary>
- /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:分钟)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForMinutesRepeatCount<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInMinutes(job.IntervalTime).WithRepeatCount(job.RepeatCount))
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:秒)
- /// <summary>
- /// 根据开始以及结束时间执行指定重复次数进行添加任务(任务间隔时间单位:秒)
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForSecondsRepeatCount<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create().WithIdentity(job.TriggerName, job.GropName).StartAt(job.StartTime).EndAt(job.EndTime)
- .WithSimpleSchedule(x => x.WithIntervalInSeconds(job.IntervalTime).WithRepeatCount(job.RepeatCount))
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- #region 通过Cron表达式添加任务
- /// <summary>
- /// 通过Cron表达式添加任务
- /// </summary>
- /// <typeparam name="T">具体任务</typeparam>
- public static void AddJobForCron<T>()
- where T : BaseJob, new()
- {
- try
- {
- T job = new T();
- IJobDetail jobDetail = JobBuilder.Create<T>().WithIdentity(job.JobName, job.GropName).Build();
- ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
- .WithIdentity(job.TriggerName, job.GropName)
- .WithCronSchedule(job.CronExpression)
- .Build();
- _scheduler.ScheduleJob(jobDetail, trigger);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- #endregion
- }
- /// <summary>
- /// 测试 job
- /// </summary>
- public class TestJob : BaseJob
- {
- public TestJob() : base("TestJob", "TestTrigger", "TestGrop",) { }
- public override void Execute(IJobExecutionContext context)
- {
- try
- {
- Console.WriteLine(string.Format("当前任务执行时间:{0}", DateTime.Now.ToString()));
- Thread.Sleep(TimeSpan.FromSeconds());
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- QuartzHelper.AddJobForSeconds<TestJob>();
- QuartzHelper.Start();
- }
- }
2、运行解决方案,得到如下结果:
发现是不是任务按照我们所希望的那样运行了,但是大家有没有注意到,TestJob中 有这样一句代码: Thread.Sleep(TimeSpan.FromSeconds(3));
- 任务是Sleep3秒钟的,可是我们的Job却一直在执行呢,即使上一次任务还没执行完,它又开始执行了。在我们的实际开发中,我们需要一次任务执行完成后再执行下一次任务。
我们对TestJob 进行改造,代码如下:
- /// <summary>
- /// 测试 job
- /// </summary>
- [DisallowConcurrentExecution]
- public class TestJob : BaseJob
- {
- public TestJob() : base("TestJob", "TestTrigger", "TestGrop",) { }
- public override void Execute(IJobExecutionContext context)
- {
- try
- {
- Console.WriteLine(string.Format("当前任务执行时间:{0}", DateTime.Now.ToString()));
- Thread.Sleep(TimeSpan.FromSeconds());
- }
- catch (Exception ex)
- {
- throw ex;
- }
- }
- }
再次运行,如图:
大家发现区别没呢,没错,我们在TestJob类上添加了“DisallowConcurrentExecution”特性,这样,就能在一次任务执行完成后,再进行下次任务的执行了。
Quartz.Net初探的更多相关文章
- Quartz.Net 学习之路02 初探Quartz.Net
第二讲:简单的实例,看看Quartz.Net强在哪里? 直接上代码,代码里有注释: using System; using Quartz; using Quartz.Impl; namespace L ...
- Quartz每次调度时被执行两次
[关键字:重复执行.重复调用.每次执行两次.执行2次] 前言: 先说一下,项目背景.由于组内某成员在用Maven搭建项目时不规范,导致项目的名称与实际访问项目名称不一致.在部署项目时,必需要配一下虚拟 ...
- 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)
很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...
- Quartz
Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. eg: ja ...
- Spring Quartz实现任务调度
任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...
- 初探领域驱动设计(2)Repository在DDD中的应用
概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...
- topshelf和quartz内部分享
阅读目录: 介绍 基础用法 调试及安装 可选配置 多实例支持及相关资料 quartz.net 上月在公司内部的一次分享,现把PPT及部分交流内容整理成博客. 介绍 topshelf是创建windows ...
- CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探
CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...
- Quartz.net持久化与集群部署开发详解
序言 我前边有几篇文章有介绍过quartz的基本使用语法与类库.但是他的执行计划都是被写在本地的xml文件中.无法做集群部署,我让它看起来脆弱不堪,那是我的罪过. 但是quart.net是经过许多大项 ...
随机推荐
- Rom Modified [Galaxy 3 Tested]
1,Virtualbox虚拟机设置-数据空间注意这里不要勾选那个自动挂载,不然后面mount总会提示mount.vbox.. invalid argument. 2,进入ubuntu中,在终端下输入 ...
- VueJS自定义全局和局部指令
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令. 使用directive自定义全局指令 下面我们注册一个全局指令 v-focus, 该指令的功能是在页面 ...
- 解决phpmyadmin导入大数据库出现一系列问题
在用phpmyadmin导入mysql数据库文件时,往往超过2M就会提示文件大,导入不成功.这时我们打开phpmyadmin-->libraries-->config.default.ph ...
- spring4.0.0的配置和使用
1.创建一个javaproject或者webproject,我创建的时webproject,编译器用的时myeclipse2013 2.在lib文件夹以下倒入spring须要的一些核心包例如以下 还需 ...
- linux memcached php 整合
http://blog.csdn.net/liruxing1715/article/details/8269563
- 一步一步 在mac上安装ubuntu
做为程序猿的你,一定听说过Linux甚至很喜欢Linux. 近期买了一台mac air,我很喜欢苹果的工艺,但作为屌丝程序猿,我依然喜欢基于Linux内核的Ubuntu 进行开发.以下我就讲述一步一步 ...
- EF Core 日志跟踪sql语句
EF Core 日志跟踪sql语句 官方文档链接:https://docs.microsoft.com/en-us/ef/core/miscellaneous/logging 1.新增自定义ILogg ...
- UITableView使用指南
本文转载至 http://blog.csdn.net/yu0089/article/details/8227402 一.概述 UITableView是iOS开发比不可少也是最重要的一个控件类.可以说任 ...
- 八大排序的python实现
以下是八大排序的python实现,供以后参考,日后扩展 一.插入排序 #-*- coding:utf-8 -*- ''' 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...
- 【BZOJ3611】[Heoi2014]大工程 欧拉序+ST表+单调栈
[BZOJ3611][Heoi2014]大工程 Description 国家有一个大工程,要给一个非常大的交通网络里建一些新的通道. 我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶 ...