概述
Quartz.NET是一個開源的做業調度框架,很是適合在平時的工做中,定時輪詢數據庫同步,定時郵件通知,定時處理數據等。 Quartz.NET容許開發人員根據時間間隔(或天)來調度做業。它實現了做業和觸發器的多對多關係,還能把多個做業與不一樣的觸發器關聯。整合了 Quartz.NET的應用程序能夠重用來自不一樣事件的做業,還能夠爲一個事件組合多個做業。數據庫
參考
https://www.quartz-scheduler.net/express
案例
第一步:安裝
新建一個QuartzDemo項目後,安裝下面的程序包app
> Install-Package Quartz
> Install-Package log4net
> Install-Package Topshelf
> Install-Package Topshelf.Log4Net
Quartz依賴Common.Logging,又由於Log4Net是比較標準的日誌工具,所以咱們通常都會安裝log4net,另外定時做業通常都容許在後臺服務中,所以咱們也安裝了Topshelf。框架
第二步:實現IJobtcp
using log4net; using Quartz; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace QuartzDemo.QuartzJobs { public sealed class TestJob : IJob { private readonly ILog _logger = LogManager.GetLogger(typeof(TestJob)); public void Execute(IJobExecutionContext context) { _logger.InfoFormat("TestJob測試"); } } }
第三步:使用Topshelf調度任務
ServiceRunner.cside
using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Topshelf; namespace QuartzDemo { public sealed 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; } } }
第四步:程序入口工具
namespace QuartzDemo { 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.SetDescription("QuartzDemo服務描述"); x.SetDisplayName("QuartzDemo服務顯示名稱"); x.SetServiceName("QuartzDemo服務名稱"); x.EnablePauseAndContinue(); }); } } }
第五步:配置quartz.config、quartz_jobs.xml、log4net.config測試
注意 這三個文件,分別選中→右鍵屬性→複製到輸入目錄設爲:始終複製this
quartz.configspa
# You can configure your scheduler in either <quartz> configuration section # 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
<?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> <!--任務名稱,同一個group中多個job的name不能相同,若未設置group則全部未設置group的job爲同一個分組(必須設置)--> <name>UserCount</name> <!--任務所屬分組,用於標識任務所屬分組--> <group>UserCount</group> <!--工做任務的描述,用於描述任務具體內容--> <description>私募版用戶統計</description> <!--任務類型,任務的具體類型及所屬程序集,格式:實現了IJob接口的包含完整命名空間的類名,程序集名稱--> <job-type>Trumgu_BI_PF.UserCountJob,Trumgu_BI_PF</job-type> <durable>true</durable> <!--<durable>(持久性)-若是一個Job是不持久的, 一旦沒有觸發器與之關聯,它就會被從scheduler 中自動刪除--> <recover>false</recover> </job> <!--trigger 任務觸發器,用於定義使用何種方式觸發任務(job),同一個job能夠定義多個trigger ,多個trigger 各自獨立的執行調度,每一個trigger 中必須且只能定義一種觸發器類型(calendar-interval、simple、cron) calendar-interval 一種觸發器類型,使用較少,此處略過--> <trigger> <!--cron複雜任務觸發器使用cron表達式定製任務調度--> <cron> <!--觸發器名稱,同一個分組中的名稱必須不一樣--> <name>UserCountTrigger</name> <!--觸發器組--> <group>UserCount</group> <!--觸發器描述--> <description>每週六14:00觸發</description> <!--要調度的任務名稱,該job-name必須和對應job節點中的name徹底相同--> <job-name>UserCount</job-name> <!--調度任務(job)所屬分組,該值必須和job中的group徹底相同--> <job-group>UserCount</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,根據規則執行任務調度,通常若無特殊須要請不要設置此屬性--> <!-- <start-time>2018-04-26T15:30:00+08:00</start-time>--> <!--cron表達式--> <cron-expression>0 0 14 ? * 7</cron-expression> </cron> </trigger> <job> <!--任務名稱,同一個group中多個job的name不能相同,若未設置group則全部未設置group的job爲同一個分組(必須設置)--> <name>Mass</name> <!--任務所屬分組,用於標識任務所屬分組--> <group>Mass</group> <!--工做任務的描述,用於描述任務具體內容--> <description>腳本執行並羣發郵件</description> <!--任務類型,任務的具體類型及所屬程序集,格式:實現了IJob接口的包含完整命名空間的類名,程序集名稱--> <job-type>Trumgu_BI_PF.MassHair,Trumgu_BI_PF</job-type> <durable>true</durable> <!--<durable>(持久性)-若是一個Job是不持久的, 一旦沒有觸發器與之關聯,它就會被從scheduler 中自動刪除--> <recover>false</recover> </job> <!--trigger 任務觸發器,用於定義使用何種方式觸發任務(job),同一個job能夠定義多個trigger ,多個trigger 各自獨立的執行調度,每一個trigger 中必須且只能定義一種觸發器類型(calendar-interval、simple、cron) calendar-interval 一種觸發器類型,使用較少,此處略過--> <trigger> <!--cron複雜任務觸發器使用cron表達式定製任務調度--> <cron> <!--觸發器名稱,同一個分組中的名稱必須不一樣--> <name>MassTrigger</name> <!--觸發器組--> <group>Mass</group> <!--觸發器描述--> <description>每週六14:30觸發</description> <!--要調度的任務名稱,該job-name必須和對應job節點中的name徹底相同--> <job-name>Mass</job-name> <!--調度任務(job)所屬分組,該值必須和job中的group徹底相同--> <job-group>Mass</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,根據規則執行任務調度,通常若無特殊須要請不要設置此屬性--> <!-- <start-time>2018-04-26T15:30:00+08:00</start-time>--> <!--cron表達式--> <cron-expression>0 30 14 ? * 7</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
log4net.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections> <log4net> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <!--日誌路徑--> <param name= "File" value= "D:\App_Log\servicelog\"/> <!--是不是向文件中追加日誌--> <param name= "AppendToFile" value= "true"/> <!--log保留天數--> <param name= "MaxSizeRollBackups" value= "10"/> <!--日誌文件名是不是固定不變的--> <param name= "StaticLogFileName" value= "false"/> <!--日誌文件名格式爲:2008-08-31.log--> <param name= "DatePattern" value= "yyyy-MM-dd".read.log""/> <!--日誌根據日期滾動--> <param name= "RollingStyle" value= "Date"/> <layout type="log4net.Layout.PatternLayout"> <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n %loggername" /> </layout> </appender> <!-- 控制檯前臺顯示日誌 --> <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender"> <mapping> <level value="ERROR" /> <foreColor value="Red, HighIntensity" /> </mapping> <mapping> <level value="Info" /> <foreColor value="Green" /> </mapping> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n%date{HH:mm:ss,fff} [%-5level] %m" /> </layout> <filter type="log4net.Filter.LevelRangeFilter"> <param name="LevelMin" value="Info" /> <param name="LevelMax" value="Fatal" /> </filter> </appender> <root> <!--(高) OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL (低) --> <level value="all" /> <appender-ref ref="ColoredConsoleAppender"/> <appender-ref ref="RollingLogFileAppender"/> </root> </log4net> </configuration>
第六步:安裝服務
cmd進入項目目錄
安裝:TopshelfDemo.exe install
啓動:TopshelfDemo.exe start
卸載:TopshelfDemo.exe uninstall
搞定============