topshelf可以很简单方便的实现windows service服务,详见我的一篇博客的介绍

http://www.cnblogs.com/xiaopotian/articles/5428361.html

Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz.NET的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。Quartz.NET是OpenSymphony的开源项目。Quartz.Net 是Quartz的C#移植版本。

它一些很好的特性:

1:支持集群,作业分组,作业远程管理。

2:自定义精细的时间触发器,使用简单,作业和触发分离。

3:数据库支持,可以寄宿Windows服务,WebSite,winform等。

下面是官网的详细介绍http://www.quartz-scheduler.net/documentation/index.html

结合topshelf、log4net与官网案例写了一个小的demo

第一步,实现IJob

 /// <summary>
/// A sample job that just prints info on console for demostration purposes.
/// </summary>
public class SampleJob : IJob
{
//private static readonly ILog logger = LogManager.GetLogger(typeof(SampleJob)); /// <summary>
/// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
/// fires that is associated with the <see cref="IJob" />.
/// </summary>
/// <remarks>
/// The implementation may wish to set a result object on the
/// JobExecutionContext before this method exits. The result itself
/// is meaningless to Quartz, but may be informative to
/// <see cref="IJobListener" />s or
/// <see cref="ITriggerListener" />s that are watching the job's
/// execution.
/// </remarks>
/// <param name="context">The execution context.</param>
public void Execute(IJobExecutionContext context)
{
LogHelper.Info("SampleJob running...");
//Thread.Sleep(TimeSpan.FromSeconds(5));
Console.WriteLine("");
LogHelper.Info("SampleJob run finished.");
}
}

第二部,配置quartz.config、quartz_jobs.xml

 # You can configure your scheduler in either quartz configuration section
# or in quartz properties file
# Configuration section has precedence quartz.scheduler.instanceName = QuartzDemo # configure thread pool info
quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount =
quartz.threadPool.threadPriority = Normal # job initialization plugin handles our xml reading, without it defaults are used
quartz.plugin.xml.type = Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz
quartz.plugin.xml.fileNames = ~/quartz_jobs.xml # export this server to remoting context
quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
quartz.scheduler.exporter.port =
quartz.scheduler.exporter.bindName = QuartzScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz
 <?xml version="1.0" encoding="UTF-8"?>

 <!-- This file contains job definitions in schema version 2.0 format -->

 <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">

   <processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives> <schedule>
<!--用来定义每个具体的任务的,多个任务请创建多个job节点即可-->
<job>
<!--name(必填) 任务名称,同一个group中多个job的name不能相同,若未设置group则所有未设置group的job为同一个分组,如:<name>sampleJob</name>-->
<name>SampleJob</name>
<!--group(选填) 任务所属分组,用于标识任务所属分组,如:<group>sampleGroup</group>-->
<group>SampleGroup</group>
<!--description(选填) 任务描述,用于描述任务具体内容,如:<description>Sample job for Quartz Server</description>-->
<description>SampleJob测试</description>
<!--job-type(必填) 任务类型,任务的具体类型及所属程序集,格式:实现了IJob接口的包含完整命名空间的类名,程序集名称,如:<job-type>Quartz.Server.SampleJob, Quartz.Server</job-type>-->
<job-type>QuartzDemo.SampleJob,QuartzDemo</job-type>
<durable>true</durable>
<recover>false</recover>
</job> <!--用于定义使用何种方式出发任务(job),同一个job可以定义多个trigger ,多个trigger 各自独立的执行调度,每个trigger 中必须且只能定义一种触发器类型(calendar-interval、simple、cron)-->
<trigger>
<!--cron复杂任务触发器,使用cron表达式定制任务调度(强烈推荐)-->
<cron>
<!--name(必填) 触发器名称,同一个分组中的名称必须不同-->
<name>TestJobTrigger</name>
<!--group(选填) 触发器组d-->
<group>Test</group>
<!--escription(选填) 触发器描述-->
<description>TestJobTriggerDescription</description>
<!--job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同-->
<job-name>SampleJob</job-name>
<!--job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同-->
<job-group>SampleGroup</job-group>
<!--start-time(选填) 任务开始执行时间utc时间,北京时间需要+:,如:<start-time>--01T08::+:</start-time>表示北京时间2012年4月1日上午8:00开始执行,注意服务启动或重启时都会检测此属性,若没有设置此属性,服务会根据cron-expression的设置执行任务调度;若start-time设置的时间比当前时间较早,则服务启动后会忽略掉cron-expression设置,立即执行一次调度,之后再根据cron-expression执行任务调度;若设置的时间比当前时间晚,则服务会在到达设置时间相同后才会应用cron-expression,根据规则执行任务调度,一般若无特殊需要请不要设置此属性-->
<start-time>--22T00::+:</start-time>
<!--cron-expression(必填) cron表达式,如:<cron-expression>/ * * * * ?</cron-expression>每10秒执行一次-->
<cron-expression>/ * * * * ?</cron-expression>
</cron>
</trigger> </schedule>
</job-scheduling-data>

log4net的配置文件没有贴出,有想看的朋友可以去源代码里面查找

第三部,结合topshelf调度任务

 public class QuartzServer
{
/// <summary>
/// 作业调度器
/// </summary>
private readonly IScheduler scheduler; public QuartzServer()
{
scheduler = StdSchedulerFactory.GetDefaultScheduler();
} /// <summary>
/// 服务启动
/// </summary>
public void Start()
{
LogHelper.Info("Start...");
scheduler.Start();
}
/// <summary>
/// 服务停止
/// </summary>
public void Stop()
{
LogHelper.Info("Stop...");
scheduler.Shutdown(false);
}
/// <summary>
/// 继续服务
/// </summary>
public void Continue()
{
LogHelper.Info("Continue...");
scheduler.ResumeAll();
}
/// <summary>
/// 服务暂停
/// </summary>
public void Pause()
{
LogHelper.Info("Pause...");
scheduler.PauseAll();
}
}

第四部,配置windows service服务,采用的通用模式

 class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service<QuartzServer>(s =>
{
//3、配置一个完全定制的服务,对Topshelf没有依赖关系。常用的方式。
s.ConstructUsing(name => new QuartzServer());
//4、服务开始的事件
s.WhenStarted(tc => tc.Start());
//5、服务停止以后事件
s.WhenStopped(tc => tc.Stop());
}); x.RunAsLocalSystem(); x.SetDescription("QuartzDemoDescription");
x.SetDisplayName("QuartzDemoDisplayName");
x.SetServiceName("QuartzDemoServiceName");
});
}
}

第五步,安装windows service服务,具体见topshelf篇

服务运行如下图

Quartz配置

quartz_jobs.xml

job 任务

其实就是1.x版本中的<job-detail>,这个节点是用来定义每个具体的任务的,多个任务请创建多个job节点即可

  • name(必填) 任务名称,同一个group中多个job的name不能相同,若未设置group则所有未设置group的job为同一个分组,如:<name>sampleJob</name>
  • group(选填) 任务所属分组,用于标识任务所属分组,如:<group>sampleGroup</group>
  • description(选填) 任务描述,用于描述任务具体内容,如:<description>Sample job for Quartz Server</description>
  • job-type(必填) 任务类型,任务的具体类型及所属程序集,格式:实现了IJob接口的包含完整命名空间的类名,程序集名称,如:<job-type>Quartz.Server.SampleJob, Quartz.Server</job-type>
  • durable(选填) 具体作用不知,官方示例中默认为true,如:<durable>true</durable>
  • recover(选填) 具体作用不知,官方示例中默认为false,如:<recover>false</recover>

trigger 任务触发器

用于定义使用何种方式出发任务(job),同一个job可以定义多个trigger ,多个trigger 各自独立的执行调度,每个trigger 中必须且只能定义一种触发器类型(calendar-interval、simple、cron)

calendar-interval 一种触发器类型,使用较少,此处略过

simple 简单任务的触发器,可以调度用于重复执行的任务

  • name(必填) 触发器名称,同一个分组中的名称必须不同
  • group(选填) 触发器组
  • description(选填) 触发器描述
  • job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同
  • job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同
  • start-time(选填) 任务开始执行时间utc时间,北京时间需要+08:00,如:<start-time>2012-04-01T08:00:00+08:00</start-time>表示北京时间2012年4月1日上午8:00开始执行,注意服务启动或重启时都会检测此属性,若没有设置此属性或者start-time设置的时间比当前时间较早,则服务启动后会立即执行一次调度,若设置的时间比当前时间晚,服务会等到设置时间相同后才会第一次执行任务,一般若无特殊需要请不要设置此属性
  • repeat-count(必填)  任务执行次数,如:<repeat-count>-1</repeat-count>表示无限次执行,<repeat-count>10</repeat-count>表示执行10次
  • repeat-interval(必填) 任务触发间隔(毫秒),如:<repeat-interval>10000</repeat-interval> 每10秒执行一次

cron复杂任务触发器--使用cron表达式定制任务调度(强烈推荐)

  • name(必填) 触发器名称,同一个分组中的名称必须不同
  • group(选填) 触发器组d
  • escription(选填) 触发器描述
  • job-name(必填) 要调度的任务名称,该job-name必须和对应job节点中的name完全相同
  • job-group(选填) 调度任务(job)所属分组,该值必须和job中的group完全相同
  • start-time(选填) 任务开始执行时间utc时间,北京时间需要+08:00,如:<start-time>2012-04-01T08:00:00+08:00</start-time>表示北京时间2012年4月1日上午8:00开始执行,注意服务启动或重启时都会检测此属性,若没有设置此属性,服务会根据cron-expression的设置执行任务调度;若start-time设置的时间比当前时间较早,则服务启动后会忽略掉cron-expression设置,立即执行一次调度,之后再根据cron-expression执行任务调度;若设置的时间比当前时间晚,则服务会在到达设置时间相同后才会应用cron-expression,根据规则执行任务调度,一般若无特殊需要请不要设置此属性
  • cron-expression(必填) cron表达式,如:<cron-expression>0/10 * * * * ?</cron-expression>每10秒执行一次

Quartz的cron表达式

官方英文介绍地址:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html

cron expressions 整体上还是非常容易理解的,只有一点需要注意:"?"号的用法,看下文可以知道“?”可以用在 day of month 和 day of week中,他主要是为了解决如下场景,如:每月的1号的每小时的31分钟,正确的表达式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因为这样代表每周的任意一天。

由7段构成:秒 分 时 日 月 星期 年(可选)
"-" :表示范围  MON-WED表示星期一到星期三
"," :表示列举 MON,WEB表示星期一和星期三
"*" :表是“每”,每月,每天,每周,每年等
"/" :表示增量:0/15(处于分钟段里面) 每15分钟,在0分以后开始,3/20 每20分钟,从3分钟以后开始
"?" :只能出现在日,星期段里面,表示不指定具体的值
"L" :只能出现在日,星期段里面,是Last的缩写,一个月的最后一天,一个星期的最后一天(星期六)
"W" :表示工作日,距离给定值最近的工作日
"#" :表示一个月的第几个星期几,例如:"6#3"表示每个月的第三个星期五(1=SUN...6=FRI,7=SAT)

官方实例

Expression Meaning
0 0 12 * * ? 每天中午12点触发
0 15 10 ? * * 每天上午10:15触发
0 15 10 * * ? 每天上午10:15触发
0 15 10 * * ? * 每天上午10:15触发
0 15 10 * * ? 2005 2005年的每天上午10:15触发
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 15 10 15 * ? 每月15日上午10:15触发
0 15 10 L * ? 每月最后一日的上午10:15触发
0 15 10 L-2 * ? Fire at 10:15am on the 2nd-to-last last day of every month
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发
0 15 10 ? * 6L Fire at 10:15am on the last Friday of every month
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发
0 0 12 1/5 * ? Fire at 12pm (noon) every 5 days every month, starting on the first day of the month.
0 11 11 11 11 ? Fire every November 11th at 11:11am.

附上demo地址

https://github.com/xiaopotian1990/QuartzDemo

quartz.net结合Topshelf实现windows service服务托管的作业调度框架的更多相关文章

  1. 震惊!Windows Service服务和定时任务框架quartz之间原来是这种关系……

    过场CG:   接到公司领导的文件指示,“小熊”需要在6月底去海外执行一个行动代号为[定时任务]的营救计划,这个计划关系到公司某个项目的生死(数据安全漏洞),作战部拟定两个作战方案: 方案一:使用务定 ...

  2. C# Windows Service服务的创建和调试

    前言 关于Windows服务创建和调试的文章在网络上的很多文章里面都有,直接拿过来贴在这里也不过仅仅是个记录,不会让人加深印象.所以本着能够更深刻了解服务项目的创建和调试过程及方法的目的,有了这篇记录 ...

  3. .Net Windows Service(服务) 调试安装及System.Timers.Timer 使用

    Windows Service(服务)  是运行在后台的进程 1.VS建立 Windows 服务(.NET Framework) 2.添加Timer 双击Service1.cs可以拖控件(System ...

  4. Windows Service 服务搭配FluentScheduler实现定时任务调度

    Windows Service 服务 创建Windows Service 项目 创建一个Windows Service项目,并将项目名称改为 TaskWindowService 在解决方案资源管理器内 ...

  5. C#制作Windows service服务系列二:演示一个定期执行的windows服务及调试(windows service)

    系列一: 制作一个可安装.可启动.可停止.可卸载的Windows service(downmoon原创) 系列二:演示一个定期执行的windows服务及调试(windows service)(down ...

  6. [开发笔记]-Windows Service服务相关注意事项

    注意一:报错:“本地计算机上的 *** 服务启动后停止.某些服务在未由其他服务或程序使用时将自动停止.” 该问题主要的原因是 Service服务程序中有错误. 遇到这个问题时,无论是重新安装服务,还是 ...

  7. war包部署在tomcat下,使用windows service服务方式启动tomcat服务器,在包含调用dll的模块,报dll找不到问题的解决办法

    问题描述: 开发了一个需要调用dll的java web程序,在idea开发环境下运行调试没问题,可以正常运行,在tomcat/bin下,运行批处理startup.bat,启动tomcat服务器,也可以 ...

  8. [开发笔记]-控制Windows Service服务运行

    用代码实现动态控制Service服务运行状态. 效果图: 代码: #region 启动服务 /// <summary> /// 启动服务 /// </summary> /// ...

  9. 使用C#编程语言开发Windows Service服务

    转载-https://www.cnblogs.com/yubao/p/8443455.html Create Windows Service project using Visual Studio C ...

随机推荐

  1. spring扩展点之一:BeanFactoryPostProcessor和BeanPostProcessor

    一.BeanFactoryPostProcessor和BeanPostProcessor的区别 BeanFactoryPostProcessor和BeanPostProcessor都是spring初始 ...

  2. webpack快速入门(二):使用入门

    继续之前请确认你已经安装了nodejs 安装.初始化: 然后找个目录新建名为webpack-demo的文件夹,然后在命令行下进入该目录,执行以下命令: npm init -y npm install ...

  3. 很漂亮的按钮css样式(没有用到图片,可直接拷贝代码使用)

    [转自]http://blog.csdn.net/lushuaiyin/article/details/8118669 对于程序员,有时候也需要对页面风格做些改动,整体的页面风格还是美工的工作. 按钮 ...

  4. css3的transition属性的使用

    transition是将某个属性从一个属性值在指定的时间内平滑过渡到另一个属性值来实现动画效果.这个属性一般搭配:hover来使 下面看一个例子:鼠标放在div上,0.2s后将div元素的背景色用一秒 ...

  5. wamp-php 集成环境的基础配置

    域名访问设置(本地局域网) 用记事本打开 127.0.0.1是本地回环地址 配置完后 通过在本地浏览器输入www.0705.com就可以访问本地站点了 Wamp集成环境多站点配置 配置条件: 一个服务 ...

  6. RESTful基础知识

    RESTful简介 互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写.翻译是"表现层状态转化". 如果一个架构符合RES ...

  7. mac 使用svn记录

    checkout  project : svn checkout svn://127.0.0.1/repository --username=username --password=password ...

  8. 函数~匿名方法~lambda的逐渐过渡思想

    前提:基于委托实现 (1)使用函数名称 delegate void Printer(string s);//(1)申明委托 static void Main(string[] args) { //(3 ...

  9. python的disutils创建分发包

    python中的distutils包主要用创建共享包,安装包,在平时安装python模块的时候,使用的命令如下: python setup.py install 其实以上代码就是distuitls包提 ...

  10. swagger 接口文档,控制器 和 object类型的参数与返回值 的 注释不显示问题

    一.控制器的注释不显示:是因为配置swagger的时候没有将includeControllerXmlComments参数配置为true,因为其默认值为false 二.object 类型的参数和返回值 ...