Quartz+TopShelf实现Windows服务作业调度

  Quartz:首先我贴出来了两段代码(下方),可以看出,首先根据配置文件(quartz.config),包装出一个Quartz.Core.QuartzScheduler

instance,这是一个调度器,调度各个任务项(Jobs)的执行。这个调度器可以被Start、被Shutdown、被PauseAll、被ResumeAll,这对应

了windows服务的开启、停止、暂停、恢复。当启动服务,我就调用调度器的Start(),停止服务我就调用调度器的Shutdown()方法。

namespace QTDemo
{
    public class ServiceRunner : ServiceControl, ServiceSuspend
    {
        private readonly IScheduler scheduler;

        public ServiceRunner()
        {
            scheduler = StdSchedulerFactory.GetDefaultScheduler();
        }

        public bool Start(HostControl hostControl)
        {
            scheduler.Start();
            return true;
        }
// 摘要:
    //     An implementation of Quartz.ISchedulerFactory that does all of it‘s work
    //     of creating a Quartz.Core.QuartzScheduler instance based on the contents
    //     of a properties file.
    public class StdSchedulerFactory : ISchedulerFactory
    {
        public const string AutoGenerateInstanceId = "AUTO";
        public const string ConfigurationSectionName = "quartz";
        public const string DefaultInstanceId = "NON_CLUSTERED";
        public const string PropertiesFile = "quartz.config";

  那TopShelf又扮演了什么样的角色呢

  这是一个宿主服务的框架。和ServiceBase、ServiceInstaller那一套的目的一样,都是用来创建Windows服务的。

项目示例

1、新建项目控制台应用程序‘QTDemo’

2、从NuGet安装‘Quartz’,‘Topshelf’,‘Topshelf.Log4Net’

1 <?xml version="1.0" encoding="utf-8"?>
2 <packages>
3   <package id="Common.Logging" version="3.3.1" targetFramework="net45" />
4   <package id="Common.Logging.Core" version="3.3.1" targetFramework="net45" />
5   <package id="log4net" version="2.0.5" targetFramework="net45" />
6   <package id="Quartz" version="2.3.3" targetFramework="net45" />
7   <package id="Topshelf" version="3.3.1" targetFramework="net45" />
8   <package id="Topshelf.Log4Net" version="3.3.1" targetFramework="net45" />
9 </packages>

3、定义一个Job(一个任务项),继承Quartz.IJob

 1 using Quartz;
 2 namespace QTDemo.QuartzJobs
 3 {
 4     public sealed class TestJob : IJob
 5     {
 6         public void Execute(IJobExecutionContext context)
 7         {
 8             CommonHelper.AppLogger.InfoFormat("TestJob测试");
 9
10         }
11     }
12 }
13  

4、配置(新建)quartz.config、quartz_jobs.xml

quartz.config可直接使用,不用修改

 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 = QuartzTest
 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 = ~/quartz_jobs.xml
15
16 # export this server to remoting context
17 #quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
18 #quartz.scheduler.exporter.port = 555
19 #quartz.scheduler.exporter.bindName = QuartzScheduler
20 #quartz.scheduler.exporter.channelType = tcp
21 #quartz.scheduler.exporter.channelName = httpQuartz

quartz_jobs.xml根据实际的Job项修改

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <!-- This file contains job definitions in schema version 2.0 format -->
 3
 4 <job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
 5
 6   <processing-directives>
 7     <overwrite-existing-data>true</overwrite-existing-data>
 8   </processing-directives>
 9
10   <schedule>
11
12     <!--TestJob测试 任务配置 -->
13     <job>
14       <name>TestJob</name>
15       <group>Test</group>
16       <description>TestJob测试</description>
17       <job-type>QTDemo.QuartzJobs.TestJob,QTDemo</job-type>
18       <durable>true</durable>
19       <recover>false</recover>
20     </job>
21     <trigger>
22       <cron>
23         <name>TestJobTrigger</name>
24         <group>Test</group>
25         <job-name>TestJob</job-name>
26         <job-group>Test</job-group>
27         <!-- 从start-time起,每5s执行一次IJob.Execute -->
28         <start-time>2012-01-22T00:00:00+08:00</start-time>
29         <cron-expression>0/5 * * * * ?</cron-expression>
30       </cron>
31     </trigger>
32
33   </schedule>
34 </job-scheduling-data>

5、创建服务

入口:

 1 using System;
 2 using System.IO;
 3 using Topshelf;
 4
 5 namespace QTDemo
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
12
16             HostFactory.Run(x =>
17             {
18                 x.UseLog4Net();
19
20                 x.Service<ServiceRunner>();
21
22                 x.RunAsLocalSystem();
23
24                 x.SetDescription("Quartz+TopShelf实现Windows服务作业调度的一个示例Demo");
25                 x.SetDisplayName("QuartzTopShelfDemo服务");
26                 x.SetServiceName("QuartzTopShelfDemoService");
27
28                 x.EnablePauseAndContinue();
29
30             });
31         }
32     }
33 }

ServiceRunner.cs

 1 using Quartz;
 2 using Quartz.Impl;
 3 using Topshelf;
 4
 5 namespace QTDemo
 6 {
 7     public class ServiceRunner : ServiceControl, ServiceSuspend
 8     {
 9         private readonly IScheduler scheduler;
10
11         public ServiceRunner()
12         {
13             scheduler = StdSchedulerFactory.GetDefaultScheduler();
14         }
15
16         public bool Start(HostControl hostControl)
17         {
18             scheduler.Start();
19             return true;
20         }
21
22         public bool Stop(HostControl hostControl)
23         {
24             scheduler.Shutdown(false);
25             return true;
26         }
27
28         public bool Continue(HostControl hostControl)
29         {
30             scheduler.ResumeAll();
31             return true;
32         }
33
34         public bool Pause(HostControl hostControl)
35         {
36             scheduler.PauseAll();
37             return true;
38         }
39
40     }
41 }

log4net配置文件,可直接使用

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   <configSections>
 4     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
 5   </configSections>
 6
 7   <log4net>
 8     <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
 9       <!--日志路径-->
10       <param name= "File" value= "Log\"/>
11       <!--是否是向文件中追加日志-->
12       <param name= "AppendToFile" value= "true"/>
13       <!--log保留天数-->
14       <param name= "MaxSizeRollBackups" value= "10"/>
15       <!--日志文件名是否是固定不变的-->
16       <param name= "StaticLogFileName" value= "false"/>
17       <!--日志文件名格式为:2008-08-31.log-->
18       <param name= "DatePattern" value= "yyyy-MM-dd&quot;.read.log&quot;"/>
19       <!--日志根据日期滚动-->
20       <param name= "RollingStyle" value= "Date"/>
21       <layout type="log4net.Layout.PatternLayout">
22         <param name="ConversionPattern" value="%date{HH:mm:ss,fff} %-5p-%m%n" />
23       </layout>
24     </appender>
25
26     <!-- 控制台前台显示日志 -->
27     <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
28       <mapping>
29         <level value="ERROR" />
30         <foreColor value="Red, HighIntensity" />
31       </mapping>
32       <mapping>
33         <level value="Info" />
34         <foreColor value="Green" />
35       </mapping>
36       <layout type="log4net.Layout.PatternLayout">
37         <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" />
38       </layout>
39
40       <filter type="log4net.Filter.LevelRangeFilter">
41         <param name="LevelMin" value="Info" />
42         <param name="LevelMax" value="Fatal" />
43       </filter>
44     </appender>
45
46     <root>
47       <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) -->
48       <level value="all" />
49       <appender-ref ref="ColoredConsoleAppender"/>
50       <appender-ref ref="RollingLogFileAppender"/>
51     </root>
52
53   </log4net>
54 </configuration>

6、quartz.config、quartz_jobs.xml、log4net.config都设置成‘始终复制’

7、直接F5,调试,发现TestJob每5s执行一次

8、安装成Windows服务

用Release编一个版本

然后用命令行安装服务

服务面板里可以查看到此服务

启动之,查看日志文件,服务运行正常

23:23:52,171 INFO -Configuration Result:
[Success] Name QuartzTopShelfDemoService
[Success] DisplayName QuartzTopShelfDemo服务
[Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
[Success] ServiceName QuartzTopShelfDemoService
23:23:52,185 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
23:23:52,194 ERROR-The QuartzTopShelfDemoService service can only be installed as an administrator
23:25:54,758 INFO -Configuration Result:
[Success] Name QuartzTopShelfDemoService
[Success] DisplayName QuartzTopShelfDemo服务
[Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
[Success] ServiceName QuartzTopShelfDemoService
23:25:54,772 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
23:25:54,781 DEBUG-Attempting to install ‘QuartzTopShelfDemoService‘
23:25:54,901 INFO -Installing QuartzTopShelfDemo服务 service
23:25:55,123 DEBUG-Opening Registry
23:25:55,123 DEBUG-Service path: "E:\DotNetProject\Y2016\QTDemo\QTDemo\bin\Release\QTDemo.exe"
23:25:55,123 DEBUG-Image path: "E:\DotNetProject\Y2016\QTDemo\QTDemo\bin\Release\QTDemo.exe"  -displayname "QuartzTopShelfDemo服务" -servicename "QuartzTopShelfDemoService"
23:25:58,357 DEBUG-Closing Registry
23:28:10,442 INFO -Configuration Result:
[Success] Name QuartzTopShelfDemoService
[Success] DisplayName QuartzTopShelfDemo服务
[Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo
[Success] ServiceName QuartzTopShelfDemoService
23:28:10,455 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.34014
23:28:10,649 DEBUG-Started by the Windows services process
23:28:10,649 DEBUG-Running as a service, creating service host.
23:28:10,651 INFO -Starting as a Windows service
23:28:10,654 DEBUG-[Topshelf] Starting up as a windows service application
23:28:10,657 INFO -[Topshelf] Starting
23:28:10,658 DEBUG-[Topshelf] Current Directory: E:\DotNetProject\Y2016\QTDemo\QTDemo\bin\Release
23:28:10,658 DEBUG-[Topshelf] Arguments:
23:28:10,940 INFO -[Topshelf] Started
23:28:10,988 INFO -TestJob测试
23:28:15,000 INFO -TestJob测试
23:28:20,000 INFO -TestJob测试

  附:源码下载

时间: 2024-10-13 11:53:47

Quartz+TopShelf实现Windows服务作业调度的相关文章

Topshelf创建Windows服务

使用Topshelf创建Windows服务 概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的介绍使用使用Topshelf创建Windows 服务.Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主. 引用安装 1.官网:http://topshelf-project.c

使用Topshelf创建Windows 服务

本文转载:http://www.cnblogs.com/aierong/archive/2012/05/28/2521409.html b.利用组件Topshelf 本方式特点:代码简单,开源组件,Windows服务可运行多个实例 Topshelf是一个开源的跨平台的服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务. 官方网站:http://topshelf-project.com 第1步:引用程序集TopShelf.dll和log4net.dll 第2步:创

【转】使用Topshelf创建Windows服务

转自:http://www.cnblogs.com/jys509/p/4614975.html 概述 Topshelf是创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with Topshelf通过5个步骤详细的介绍使用使用Topshelf创建Windows 服务.Topshelf是一个开源的跨平台的宿主服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务宿主. 引用安装 1.官网

使用Topshelf 开发windows服务

在业务系统中,我们为了调度一些自动执行的任务或从队列中消费一些消息,所以基本上都会涉及到后台服务的开发.如果用windows service开发,非常不爽的一件事就是:调试相对麻烦,而且你还需要了解 windows service 相关的一些开发和安装部署,所以,windows service非常的不方便.Topshelf框架,能够让你将 console application 直接封装为 windows service,这样你在开发的时候,就可以直接在console 程序上开发,然后构成win

如何使用Topshelf管理Windows服务

一.官方网站及源码下载 1.官方网站:http://topshelf-project.com/ 2.源码下载:https://github.com/Topshelf/Topshelf/downloads 二.使用Topshelf创建服务 1 static void Main(string[] args) 2 { 3 HostFactory.Run(x => 4 { 5 x.Service<MyService>(dtService => 6 { 7 ServiceConfigurat

Quartz.Net在windows服务中的使用

写在前面 这几天在弄一个项目,需要定时抓取一些数据,当时也想直接用timer算了.因为之前也弄过这样的项目,但是一想,已经用过了,再去使用同一种思路,未免太乏味了.就换了一种新玩法.这里将之前看到的一篇文章中提出的一个思路,在这个项目中实践了一下,发现乐在其中. Quarzt.net [转]C#创建服务及使用程序自动安装服务,.NET创建一个即是可执行程序又是Windows服务的exe 这篇文章,给了一种好玩的方式,并且自己也实践了一下,而且也确确实实在项目中用到了. 简单一个demo,先熟悉如

使用Topshelf创建Windows服务

本方式特点:代码简单,开源组件,Windows服务可运行多个实例 Topshelf是一个开源的跨平台的服务框架,支持Windows和Mono,只需要几行代码就可以构建一个很方便使用的服务. 官方网站:http://topshelf-project.com 第1步:引用程序集TopShelf.dll和log4net.dll 第2步:创建一个服务类MyClass,里面包含两个方法Start和Stop,还包含一个定时器Timer,每隔5秒往文本文件中写入字符 public class MyClass

使用Topshelf管理Windows服务

一.官方网站及源码下载 1.官方网站:http://topshelf-project.com/ 2.源码下载:https://github.com/Topshelf/Topshelf/downloads 二.Topshelf优势 1.调试方便:不用创建windows服务项目,直接创建控制台程序即可,启动控制台就可以进行服务代码调试 2.安装/卸载服务方法           1.cmd-->cd 程序目录(直接定位到exe文件所在目录) 2.安装服务:JwifiRoute.Message.Log

ASP.NET Core使用TopShelf部署Windows服务

asp.net core很大的方便了跨平台的开发者,linux的开发者可以使用apache和nginx来做反向代理,windows上可以用IIS进行反向代理. 反向代理可以提供很多特性,固然很好.但是还有复杂性,我们也可以使用windows service来直接启动kestrel. asp.net core官方网站提供了一种基于windows服务部署的方法:在 Windows 服务中托管 ASP.NET Core 这种方式需要修改代码,然后部署的时候,使用命令行创建.安装服务,然后再启动. 感觉