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’
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Common.Logging" version="3.3.1" targetFramework="net45" />
<package id="Common.Logging.Core" version="3.3.1" targetFramework="net45" />
<package id="log4net" version="2.0.5" targetFramework="net45" />
<package id="Quartz" version="2.3.3" targetFramework="net45" />
<package id="Topshelf" version="3.3.1" targetFramework="net45" />
<package id="Topshelf.Log4Net" version="3.3.1" targetFramework="net45" />
</packages>
3、定义一个Job(一个任务项),继承Quartz.IJob
namespace QTDemo.QuartzJobs
{
public sealed class TestJob : IJob
{
public void Execute(IJobExecutionContext context)
{
CommonHelper.AppLogger.InfoFormat("TestJob测试");
}
}
}
4、配置(新建)quartz.config、quartz_jobs.xml
quartz.config可直接使用,不用修改
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
# or in quartz properties file
# Configuration section has precedence
quartz.scheduler.instanceName = QuartzTest
# configure thread pool info
quartz.threadPool.type = Quartz.Simpl.SimpleThreadPool, Quartz
quartz.threadPool.threadCount = 10
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 = 555
#quartz.scheduler.exporter.bindName = QuartzScheduler
#quartz.scheduler.exporter.channelType = tcp
#quartz.scheduler.exporter.channelName = httpQuartz
quartz_jobs.xml根据实际的Job项修改
<?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>
<!--TestJob测试 任务配置 -->
<job>
<name>TestJob</name>
<group>Test</group>
<description>TestJob测试</description>
<job-type>QTDemo.QuartzJobs.TestJob,QTDemo</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>TestJobTrigger</name>
<group>Test</group>
<job-name>TestJob</job-name>
<job-group>Test</job-group>
<!-- 从start-time起,每5s执行一次IJob.Execute -->
<start-time>2012-01-22T00:00:00+08:00</start-time>
<cron-expression>0/5 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
5、创建服务
入口:
using System;
using System.IO;
using Topshelf;
namespace QTDemo
{
class Program
{
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
HostFactory.Run(x =>
{
x.UseLog4Net();
x.Service<ServiceRunner>();
x.RunAsLocalSystem();
x.SetDescription("Quartz+TopShelf实现Windows服务作业调度的一个示例Demo");
x.SetDisplayName("QuartzTopShelfDemo服务");
x.SetServiceName("QuartzTopShelfDemoService");
x.EnablePauseAndContinue();
});
}
}
}
ServiceRunner.cs
using Quartz;
using Quartz.Impl;
using Topshelf;
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;
}
public bool Stop(HostControl hostControl)
{
scheduler.Shutdown(false);
return true;
}
public bool Continue(HostControl hostControl)
{
scheduler.ResumeAll();
return true;
}
public bool Pause(HostControl hostControl)
{
scheduler.PauseAll();
return true;
}
}
}
log4net配置文件,可直接使用
6、quartz.config、quartz_jobs.xml、log4net.config都设置成‘始终复制’
7、直接F5,调试,发现TestJob每5s执行一次
8、安装成Windows服务
用Release编一个版本
然后用命令行安装服务
服务面板里可以找到此服务
启动之,查看日志文件,服务运行正常