你的位置:首页 > ASP.net教程

[ASP.net教程]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 <?"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.

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 = 1010 quartz.threadPool.threadPriority = Normal11 12 # job initialization plugin handles our 13 quartz.plugin. Quartz.Plugin.14 quartz.plugin.quartz_jobs.15 16 # export this server to remoting context17 #quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz18 #quartz.scheduler.exporter.port = 55519 #quartz.scheduler.exporter.bindName = QuartzScheduler20 #quartz.scheduler.exporter.channelType = tcp21 #quartz.scheduler.exporter.channelName = httpQuartz

View Code

quartz_jobs.

 1 <??> 2 <!-- This file contains job definitions in schema version 2.0 format --> 3  4 <job-scheduling-data ="http://quartznet.sourceforge.net/JobSchedulingData" ="http://www.w3.org/2001/ 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.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 <??> 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>

View Code 

 

6、quartz.config、quartz_jobs.

 

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 QuartzTopShelfDemoService23:23:52,185 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.3401423:23:52,194 ERROR-The QuartzTopShelfDemoService service can only be installed as an administrator23:25:54,758 INFO -Configuration Result:[Success] Name QuartzTopShelfDemoService[Success] DisplayName QuartzTopShelfDemo服务[Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo[Success] ServiceName QuartzTopShelfDemoService23:25:54,772 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.3401423:25:54,781 DEBUG-Attempting to install 'QuartzTopShelfDemoService'23:25:54,901 INFO -Installing QuartzTopShelfDemo服务 service23:25:55,123 DEBUG-Opening Registry23: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 Registry23:28:10,442 INFO -Configuration Result:[Success] Name QuartzTopShelfDemoService[Success] DisplayName QuartzTopShelfDemo服务[Success] Description Quartz+TopShelf实现Windows服务作业调度的一个示例Demo[Success] ServiceName QuartzTopShelfDemoService23:28:10,455 INFO -Topshelf v3.3.154.0, .NET Framework v4.0.30319.3401423:28:10,649 DEBUG-Started by the Windows services process23:28:10,649 DEBUG-Running as a service, creating service host.23:28:10,651 INFO -Starting as a Windows service23:28:10,654 DEBUG-[Topshelf] Starting up as a windows service application23:28:10,657 INFO -[Topshelf] Starting23:28:10,658 DEBUG-[Topshelf] Current Directory: E:\DotNetProject\Y2016\QTDemo\QTDemo\bin\Release23:28:10,658 DEBUG-[Topshelf] Arguments: 23:28:10,940 INFO -[Topshelf] Started23:28:10,988 INFO -TestJob测试23:28:15,000 INFO -TestJob测试23:28:20,000 INFO -TestJob测试

 

  附:源码下载