Quartz.NET Windows
想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度引入进来了,那今天就简单的介绍一下 Quartz.NET 基于 Windows 服务宿主是怎样配置使用的。
Quartz.NET 是一个优秀的任务调度框架,移植于 Java 版的 Quartz 。
示例环境
- .Net 4.5.2
- Quartz 2.4.1
- Common.Logging 3.3.1
- log4net 2.0.5
- Common.Logging.Log4Net1213 3.3.1
源码地址:https://github.com/Wlitsoft/QuartzNETWinServiceSample
配置
1. quartz.config
这个配置文件需要放在服务运行根目录下,用于指定 quartz 的一些运行配置,比如调度名称、线程池实现组件、线程池大小、任务配置文件路径等。

- 1 # You can configure your scheduler in either <quartz> configuration section
- 2 # or in quartz properties file
- 3 # Configuration section has precedence
- 4
- 5 quartz.scheduler.instanceName = QuartzNETWinServiceScheduler
- 6
- 7 # configure thread pool info
- 8 quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
- 9 quartz.threadPool.threadCount = 10
- 10 quartz.threadPool.threadPriority = Normal
- 11
- 12 # job initialization plugin handles our xml reading, without it defaults are used
- 13 quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
- 14 quartz.plugin.xml.fileNames = ~/Conf/jobs.config

暂时需求需要修改的只有一处,看最后一行 quartz.plugin.xml.fileNames = ~/Conf/jobs.config 指定任务的配置文件路径。
2. 任务配置文件

- 1 <?xml version="1.0" encoding="UTF-8"?>
- 2 <!-- This file contains job definitions in schema version 2.0 format -->
- 3 <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
- 4
- 5 <processing-directives>
- 6 <overwrite-existing-data>true</overwrite-existing-data>
- 7 </processing-directives>
- 8
- 9 <schedule>
- 10 <job>
- 11 <name>Job1</name>
- 12 <group>Jobs</group>
- 13 <description>任务1</description>
- 14 <job-type>Wlitsoft.ProjectSample.QuartzNETWinService.Job.Job1,QuartzNETWinService</job-type>
- 15 <durable>true</durable>
- 16 <recover>false</recover>
- 17 </job>
- 18 <trigger>
- 19 <simple>
- 20 <name>Job1Trigger</name>
- 21 <group>Jobs</group>
- 22 <description>每 30 秒执行一次</description>
- 23 <job-name>Job1</job-name>
- 24 <job-group>Jobs</job-group>
- 25 <repeat-count>-1</repeat-count>
- 26 <repeat-interval>30000</repeat-interval>
- 27 </simple>
- 28 </trigger>
- 29 </schedule>
- 30 </job-scheduling-data>

以下为配置文件属性:
- 任务 (job 节点)
simple 节点项说明 | ||||
名称 | 类型 | 是否必填 | 默认值 | 描述 |
name | string | Y | 触发器名称 | |
group | string | N | 默认组名 | 触发器名称 |
description | string | N | 触发器描述 | |
job-name | string | Y | 要触发的任务的名称 | |
job-group | string | Y | 要触发的任务的组名称 | |
durable | boolean | N | false | 任务完成后是否依然保存到数据库 |
recover | boolean | N | false | 应用或服务重启之后是否忽略过期任务 |
- 触发器 (trigger 节点)
下面说下最常用的两种触发器:
1)简单触发器(simple 节点)用于触发定时轮训执行的任务。
simple 节点项说明 | ||||
名称 | 类型 | 是否必填 | 默认值 | 描述 |
name | string | Y | 触发器名称 | |
group | string | N | 默认组名 | 触发器名称 |
description | string | N | 触发器描述 | |
job-name | string | Y | 要触发的任务的名称 | |
job-group | string | Y | 要触发的任务的组名称 | |
repeat-count | int | Y | 0 | 重复次数(0:不执行;-1:不限次数) |
repeat-interval | long | Y | 0 | 间隔时间(单位:毫秒) |
start-time | date | N | 当前时间 | 开始时间 |
end-time | date | N | 结束时间(如果不指定则一直执行直到重复次数) |
2)Cron 触发器(cron 节点)根据 cron 表达式触发任务。
cron 节点项说明 | ||||
名称 | 类型 | 是否必填 | 默认值 | 描述 |
name | string | Y | 触发器名称 | |
group | string | N | 默认组名 | 触发器名称 |
description | string | N | 触发器描述 | |
job-name | string | Y | 要触发的任务的名称 | |
job-group | string | Y | 要触发的任务的组名称 | |
cron | string | Y | 规则表达式 | |
start-time | date | N | 当前时间 | 开始时间 |
end-time | date | N | 结束时间 |
注:cron 表达式在线生成:http://cron.qqe2.com
3. 日志配置文件
1) app.config
- configSctions
- 1 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
- 2 <sectionGroup name="common">
- 3 <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
- 4 </sectionGroup>
- commong.logging 配置

- 1 <common>
- 2 <logging>
- 3 <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1213">
- 4 <arg key="configType" value="FILE-WATCH" />
- 5 <arg key="configFile" value="~/Conf/log4net.config" />
- 6 <arg key="level" value="INFO" />
- 7 </factoryAdapter>
- 8 </logging>
- 9 </common>

- configType : 用于指定日子配置文件类型,取值:INLINE - 在当前配置文件总;FILE-WATCH - 配置文件中。
- configFile:配置文件路径。
- level:日子输出级别。
- log4net 配置
主程序代码:

- 1 using System.ServiceProcess;
- 2 using Common.Logging;
- 3 using Quartz;
- 4 using Quartz.Impl;
- 5
- 6 namespace Wlitsoft.ProjectSample.QuartzNETWinService
- 7 {
- 8 public partial class MainService : ServiceBase
- 9 {
- 10 #region 私有属性
- 11
- 12 //日志记录这。
- 13 private readonly ILog _logger;
- 14
- 15 //调度器。
- 16 private readonly IScheduler _scheduler;
- 17
- 18 #endregion
- 19
- 20 #region 构造方法
- 21
- 22 /// <summary>
- 23 /// 初始化 <see cref="MainService"/> 类的新实例。
- 24 /// </summary>
- 25 public MainService()
- 26 {
- 27 InitializeComponent();
- 28 this._logger = LogManager.GetLogger(this.GetType());
- 29 StdSchedulerFactory factory = new StdSchedulerFactory();
- 30 this._scheduler = factory.GetScheduler();
- 31 }
- 32
- 33 #endregion
- 34
- 35 protected override void OnStart(string[] args)
- 36 {
- 37 this._scheduler.Start();
- 38 this._logger.Info("服务启动");
- 39 }
- 40
- 41 protected override void OnStop()
- 42 {
- 43 if (!this._scheduler.IsShutdown)
- 44 this._scheduler.Shutdown();
- 45 this._logger.Info("服务停止");
- 46 }
- 47
- 48 protected override void OnPause()
- 49 {
- 50 this._scheduler.PauseAll();
- 51 base.OnPause();
- 52 }
- 53
- 54 protected override void OnContinue()
- 55 {
- 56 this._scheduler.ResumeAll();
- 57 base.OnContinue();
- 58 }
- 59 }
- 60 }

示例任务代码:

- 1 using Common.Logging;
- 2 using Quartz;
- 3
- 4 namespace Wlitsoft.ProjectSample.QuartzNETWinService.Job
- 5 {
- 6 public class Job1 : IJob
- 7 {
- 8 //日志构造者。
- 9 private static readonly ILog Logger = LogManager.GetLogger("job1");
- 10
- 11 #region Implementation of IJob
- 12
- 13 /// <summary>
- 14 /// Called by the <see cref="T:Quartz.IScheduler" /> when a <see cref="T:Quartz.ITrigger" />
- 15 /// fires that is associated with the <see cref="T:Quartz.IJob" />.
- 16 /// </summary>
- 17 /// <remarks>
- 18 /// The implementation may wish to set a result object on the
- 19 /// JobExecutionContext before this method exits. The result itself
- 20 /// is meaningless to Quartz, but may be informative to
- 21 /// <see cref="T:Quartz.IJobListener" />s or
- 22 /// <see cref="T:Quartz.ITriggerListener" />s that are watching the job's
- 23 /// execution.
- 24 /// </remarks>
- 25 /// <param name="context">The execution context.</param>
- 26 public void Execute(IJobExecutionContext context)
- 27 {
- 28 string jobDes = context.JobDetail.Description;
- 29 Logger.Info($"{jobDes}运行");
- 30 }
- 31
- 32 #endregion
- 33 }
- 34 }

源码地址:https://github.com/Wlitsoft/QuartzNETWinServiceSample
推荐阅读:一个技术汪的开源梦
Quartz.NET Windows的更多相关文章
- .net core+topshelf+quartz创建windows定时任务服务
.net core+topshelf+quartz创建windows定时任务服务 准备工作 创建.net core 控制台应用程序,这里不做过多介绍 添加TopShelf包:TopShelf: 添加Q ...
- Quartz.NET Windows 服务示例
想必大家在项目中处理简单的后台持续任务或者定时触发任务的时候均使用 Thread 或者 Task 来完成,但是项目中的这种需求一旦多了的话就得将任务调度引入进来了,那今天就简单的介绍一下 Quartz ...
- Topshelf+Quartz实现windows任务
Topshelf使用示例, HostFactory.Run(x => { x.Service<QuartzStartup>(s => { s.ConstructUsing(na ...
- Quartz和TopShelf Windows服务作业调度
上一次写了一遍关于Quartz作业调度的文章 Quartz.NET 作业调度使用 现在使用TopShelf和Quartz实现windows服务作业调度 TopShelf版本4.0 Quartz版本3. ...
- 震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……
过场CG: 接到公司领导的文件指示,“小熊”需要在6月底去海外执行一个行动代号为[定时任务]的营救计划,这个计划关系到公司某个项目的生死(数据安全漏洞),作战部拟定两个作战方案: 方案一:使用务定 ...
- Python基础系列讲解-自动控制windows桌面
原链接:https://zhuanlan.zhihu.com/p/73001806 在使用PC时与PC交互的主要途径是看屏幕显示.听声音,点击鼠标和敲键盘等等.在自动化办公的趋势下,繁琐的工作可以让程 ...
- 从输入 URL 到浏览器接收的过程中发生了什么事情
从输入 URL 到浏览器接收的过程中发生了什么事情? 原文:http://www.codeceo.com/article/url-cpu-broswer.html 从触屏到 CPU 首先是「输入 U ...
- [python] PyMouse、PyKeyboard用python操作鼠标和键盘
1.PyUserInput 简介 PyUserInput是一个使用python的跨平台的操作鼠标和键盘的模块,非常方便使用.支持的平台及依赖如下: Linux - Xlib Mac - Quart ...
- Open Source
资源来源于http://www.cnblogs.com/Leo_wl/category/246424.html RabbitMQ 安装与使用 摘要: RabbitMQ 安装与使用 前言 吃多了拉就是队 ...
随机推荐
- JSF 监听
JSF项目中实现基于RBAC模型的权限管理设计(二) 转 4.3 权限验证模块设计 一个好的权限管理机制在项目中应用时,最好不要让程序员在具体业务代码的方法中来判断用户权限.因为这意味着大量重复的代码 ...
- oracle 强杀进程
在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid,serial#'杀掉一个会话进程,但是使用这个SQL语句杀掉会话后,数据库并不会立即释放掉相关的资源 ...
- Windows Phone零距离开发(Composite Thread组合线程)
简洁流畅,快速响应是Windows Phone的特点也是他的买点,我们在开发App时候,也要在手机有限的硬件性能上最大限度做到UI快速响应,微软在优化手机快速响应这块做了很多底层优化工作,其中有一个就 ...
- .NET中的计时器控件Timer
本章借介绍一些粗浅的Timer控件使用方法. 介绍Timer控件的常用属性和事件 1. Interval 属性表示 Timer控件的时间间隔. 类型是int默认是毫秒. 2. Enabled 属性 表 ...
- compareTo & toString
public class UnAssignedRecord implements Comparable<UnAssignedRecord> { private String time; / ...
- ThinkPHP之中的getField、Find、select、返回数据类型详解(ThinkPHP之中所有数据读取了)
小李子:用于演示作用的数据库表:customers 官方解读: “ 读取数据集其实就是获取数据表中的多行记录(以及关联数据),使用select方法 ” $customers=D('customers' ...
- 亚信联创--java面试题目总结
这几天投简历,只有两家的HR表示感兴趣.易思卓越和亚信联创,不管怎样如果能有机会面试都一定尽力表现,所以找了找网上的面经,这里先把题目总结一下. 职位要求如下: ------------------- ...
- ajax+php+mysql更新
html代码 <input type="button" id="quxiao" class="quxiao" name="q ...
- 【转】Linux Soclet编程
原文地址:http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编 ...
- Test,Nginx Hello World Module
ngx_addon_name=ngx_http_mytest_module HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module" ...