Quartz.Net簡介
Quartz.NET是一個用C#編寫的業調度框架
創建步驟:
1.創建一個控制台程序
.Net框架使用4.6.1
2.使用Nugget添加Quartz,Quartz.Plugins[2.x版本不需要]
3.創建Job
public class HelloJob : IJob { private static int ii = 0; public string Name { private get; set; }//使用依賴JobFactory將數據映射值“注入”到類中;如IJobDetail與ITrigger都設置了Name,則ITrigger會覆蓋IJobDetail的值 public async Task Execute(IJobExecutionContext context) { ii++; await System.Console.Out.WriteLineAsync(string.Format("Key:{0}", context.JobDetail.Key)); } }
public class HelloWord : IJob { public async Task Execute(IJobExecutionContext context) { //string name = context.JobDetail.JobDataMap.GetString("name"); //await Console.Out.WriteLineAsync(string.Format("Key:{0}", context.JobDetail.Key)); await Console.Out.WriteLineAsync(string.Format("Execute DateTime:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); } }
4.在代碼里面配置觸發器
private static async Task RunProgramRunExample() { try { // Grab the Scheduler instance from the Factory NameValueCollection props = new NameValueCollection { { "quartz.serializer.type", "binary" } }; StdSchedulerFactory factory = new StdSchedulerFactory(); IScheduler scheduler = await factory.GetScheduler(); // and start it off await scheduler.Start(); DateTimeOffset dateTimeOffset = DateTimeOffset.Now.AddSeconds(5); // define the job and tie it to our HelloJob class IJobDetail job0 = JobBuilder.Create<HelloJob>() .WithIdentity("job11", "group0") .UsingJobData("Name", "IJobDetail") .Build(); // Trigger the job to run now, and then repeat every 10 seconds ITrigger trigger0 = TriggerBuilder.Create() .WithIdentity("trigger1", "group0") .StartAt(dateTimeOffset) //.StartNow()//設置馬上啟動觸發器 //.StartAt(DateTimeOffset.Now.AddDays(1))//設置一天后執行,如設置的時間小於當前時間則立即執行 .WithSimpleSchedule(x => x//設置執行計划 .WithIntervalInSeconds(1)//間隔1s執行 .RepeatForever()//永遠執行下去 //.WithRepeatCount(10)//執行10就不再執行,測試其實會執行11次 ) //.EndAt(new DateTimeOffset(DateTime.Now.AddSeconds(5)))//當前時間+5s后結束執行 .UsingJobData("Name", "ITrigger") .WithPriority(11)//設置觸發器優先級,當有多個觸發器在相同時間出發時,優先級最高[數字最大]的優先 .Build(); var job1 = JobBuilder.Create<HelloWord>() .WithIdentity("job100", "group1") .UsingJobData("name", "Quartz.Net")//設置在Job所需要的參數,通過context.JobDetail.JobDataMap.GetString("name")獲取 .Build(); var trigger1 = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .StartAt(dateTimeOffset) //.StartNow() .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever()) .UsingJobData("name", "QuartZ...")//設置在Job所需要的參數,通過context.Trigger.JobDataMap.GetString("name")獲取 .WithPriority(100) .Build(); // Tell quartz to schedule the job using our trigger //await scheduler.ScheduleJob(job0, trigger0); #region 日歷 //創建所有的假期;如只添加兩天,則只有這兩天是假期 var cal = new HolidayCalendar(); cal.AddExcludedDate(DateTime.Now); cal.AddExcludedDate(DateTime.Now.AddDays(2)); var aa = cal.ExcludedDates;//只返回日期部分 await scheduler.AddCalendar("myHolidays", cal, true, true); #endregion var dic = new Dictionary<IJobDetail, IReadOnlyCollection<ITrigger>>(); dic.Add(job0, new HashSet<ITrigger>() { trigger0 }); dic.Add(job1, new HashSet<ITrigger>() { trigger1 }); await scheduler.ScheduleJobs(dic, true); //while (true) //{ // // some sleep to show what's happening // await Task.Delay(TimeSpan.FromSeconds(6)); //} //// and last shut down the scheduler when you are ready to close your program //await scheduler.Shutdown(); #region CronTriggers //每天上午8點到17點之間每隔一分鍾觸發一次 var t = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0 0/1 8-17 * * ?") .ForJob(job1) .Build(); //每天上午10: 42開火 var t1 = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("0 42 10 * * ?") .ForJob(job1) .Build(); t1 = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(10, 42)) .Build(); #endregion } catch (SchedulerException se) { System.Console.WriteLine(se); } }
在main里面調用RunProgramRunExample即可;
5.使用配置文件配置觸發器
1.添加quartz.config[需要與app.config在同級不然找不到]
# 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.Plugins #指定quartz_jobs.xml路徑
quartz.plugin.xml.fileNames = ~/quartz_jobs.xml # export this server to remoting context 使用CrystalQuartz 放開如下注釋 #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
2.添加quartz_jobs.xml配置文件[可以放到任意目錄,因為在quartz.config指定路徑]
core配置規則見:https://www.quartz-scheduler.net/documentation/quartz-3.x/tutorial/crontrigger.html
<?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>QuartzNet.HelloWord,QuartzNet</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>2015-01-22T00:00:00+08:00</start-time> <cron-expression>0/3 * * * * ?</cron-expression> </cron> </trigger> </schedule> </job-scheduling-data>
3.將以上配置文件的'復制到輸出目錄'修改為'始終復制'
5.如需要將控制台程序做Windows服務,則如Nugget中添加Topshelf,Topshelf.Log4Net;然后創建
public class ServiceRunner : ServiceControl, ServiceSuspend { private readonly IScheduler scheduler; public ServiceRunner() { StdSchedulerFactory factory = new StdSchedulerFactory(); scheduler = factory.GetScheduler().Result; } public bool Start(HostControl hostControl) { scheduler.Start(); return true; } public bool Stop(HostControl hostControl) { scheduler.Shutdown(true); return true; } public bool Continue(HostControl hostControl) { scheduler.ResumeAll(); return true; } public bool Pause(HostControl hostControl) { scheduler.PauseAll(); return true; } }
main代碼:
static void Main(string[] args) { HostFactory.Run(x => { x.UseLog4Net(); x.Service<ServiceRunner>(); x.SetDescription("調度服務"); x.SetDisplayName("AutoTask"); x.SetServiceName("AutoTask"); x.EnablePauseAndContinue(); }); }
編譯程序,在cmd[需使用管理員權限運行]執行 install即可
啟動服務即可;
6.使用CrystalQuartz管理Quartz.Net
1.創建一個空的Asp.Net項目;
2.用Nuget添加CrystalQuartz.Remote;
3.在web.config的configuration/crystalQuartz/provider節點下添加需管理的Quartz.Net的的路徑;配置文件如下:

1 <?xml version="1.0" encoding="utf-8"?> 2 <!-- 3 有關如何配置 ASP.NET 應用程序的詳細信息,請訪問 4 https://go.microsoft.com/fwlink/?LinkId=169433 5 --> 6 <configuration> 7 <configSections> 8 <sectionGroup name="crystalQuartz" type="CrystalQuartz.Web.Configuration.CrystalQuartzConfigurationGroup"> 9 <section name="provider" type="CrystalQuartz.Web.Configuration.ProviderSectionHandler" requirePermission="false" allowDefinition="Everywhere" /> 10 </sectionGroup> 11 </configSections> 12 <system.web> 13 <compilation debug="true" targetFramework="4.6.1" /> 14 <httpRuntime targetFramework="4.6.1" /> 15 </system.web> 16 <crystalQuartz> 17 <provider> 18 <add property="Type" value="CrystalQuartz.Core.SchedulerProviders.RemoteSchedulerProvider, CrystalQuartz.Core" /> 19 <!-- Edit scheduler host value below =================================== --> 20 <add property="SchedulerHost" value="tcp://localhost:555/QuartzScheduler" /> 21 <add property="SchedulerHost" value="tcp://localhost:9999/QuartzScheduler" /> 22 <!-- =================================== --> 23 </provider> 24 </crystalQuartz><appSettings /><connectionStrings /><system.webServer> 25 <handlers> 26 <add name="CrystalQuartzPanel" verb="*" path="CrystalQuartzPanel.axd" type="CrystalQuartz.Web.PagesHandler, CrystalQuartz.Web" /> 27 </handlers> 28 </system.webServer> 29 <runtime> 30 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 31 <dependentAssembly> 32 <assemblyIdentity name="Quartz" publicKeyToken="f6b8c98a402cc8a4" culture="neutral" /> 33 <bindingRedirect oldVersion="0.0.0.0-3.0.6.0" newVersion="3.0.6.0" /> 34 </dependentAssembly> 35 </assemblyBinding> 36 </runtime> 37 <system.codedom> 38 <compilers> 39 <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" /> 40 <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" /> 41 </compilers> 42 </system.codedom> 43 </configuration>
4.在quartz.config中配置
# export this server to remoting context 使用CrystalQuartz 放開如下注釋
quartz.scheduler.exporter.type = Quartz.Simpl.RemotingSchedulerExporter, Quartz
#指定端口號,即CrystalQuartz需要監視的端口號
quartz.scheduler.exporter.port = 555
quartz.scheduler.exporter.bindName = QuartzScheduler
quartz.scheduler.exporter.channelType = tcp
quartz.scheduler.exporter.channelName = httpQuartz
5.在IIS添加CrystalQuartz所屬ASP.NET的站點;然后在站點后加上/CrystalQuartzPanel.axd即可;
我偷個懶,沒有部署站點,直接在VS中運行;上圖可以看過我們在Quartz.NET中配置的Job和其所屬的觸發器;
觸發器也可以在管理里面中添加如下圖:
也可以刪除或立即啟動相應的觸發器