安装 Quartz 程序包
使用 nuget 命令行安装 Quartz:
Install-Package Quartz
如果使用 JSON 序列化,使用 nuget 安装 Quartz.Serialization.Json。
配置 Quartz
可通过三种方式配置Quartz
- 编程式配置,用 NameValueCollection 为 SchedulerFactory 提供参数
- 通过 app.config 文件,这种方式仅适用于 full .net framework
- 通过 quartz.config,此文件需放在应用程序的根目录,这种方式适用于 full .net framework 和 .net core
程序骨架
以下代码创建 Scheduler 实例,启动它,最后关闭。
using System;using System.Collections.Specialized;using System.Threading.Tasks;using Quartz;using Quartz.Impl;namespace QuartzSampleApp{ ???public class Program ???{ ???????private static void Main(string[] args) ???????{ ???????????// 异步执行 ???????????RunProgram().GetAwaiter().GetResult(); ???????} ???????private static async Task RunProgram() ???????{ ???????????try ???????????{ ???????????????// 从工厂获取 Scheduler 实例 ???????????????NameValueCollection props = new NameValueCollection ???????????????{ ???????????????????{ "quartz.serializer.type", "binary" } ???????????????}; ???????????????StdSchedulerFactory factory = new StdSchedulerFactory(props); ???????????????IScheduler scheduler = await factory.GetScheduler(); ???????????????// 启动 Scheduler 实例 ???????????????await scheduler.Start(); ???????????????// 停60秒看效果 ???????????????await Task.Delay(TimeSpan.FromSeconds(60)); ???????????????// 关闭程序前关闭 scheduler ???????????????await scheduler.Shutdown(); ???????????} ???????????catch (SchedulerException se) ???????????{ ???????????????await Console.Error.WriteLineAsync(se.ToString()); ???????????} ???????} ???}}
通过 StdSchedulerFactory.GetDefaultScheduler() 方法获取到 scheduler 实例后,直到调用 scheduler.Shutdown() 前,应用程序不会退出。因为存在后台线程。
添加日志
Quartz.net 使用 LibLog,可适配 Log4Net,NLog 和Serilog等日志框架。没有检测到这些日志框架时,LibLog不输出内容。下面的自定义 LoggerProvider 在没有使用日志框架的情况下向控制台输出消息:
private class ConsoleLogProvider : ILogProvider{ ???public Logger GetLogger(string name) ???{ ???????return (level, func, exception, parameters) => ???????{ ???????????if (level >= LogLevel.Info && func != null) ???????????{ ???????????????Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters); ???????????} ???????????return true; ???????}; ???} ???public IDisposable OpenNestedContext(string message) ???{ ???????throw new NotImplementedException(); ???} ???public IDisposable OpenMappedContext(string key, string value) ???{ ???????throw new NotImplementedException(); ???}}
使用自定义LogProvider:
???????private static void Main(string[] args) ???????{ ???????????LogProvider.SetCurrentLogProvider(new ConsoleLogProvider()); ???????????// 异步执行 ???????????RunProgram().GetAwaiter().GetResult(); ???????}
添加作业
使用 IJob 接口自定义作业
???public class HelloJob : IJob ???{ ???????public async Task Execute(IJobExecutionContext context) ???????{ ???????????await Console.Out.WriteLineAsync("Greetings from HelloJob!"); ???????} ???}
使用作业,在调用 Start 方法之后加入以下代码:
???????// 定义作业,关联到 HelloJob ???????IJobDetail job = JobBuilder.Create<HelloJob>() ???????????.WithIdentity("job1", "group1") ???????????.Build(); ???????// 立即触发,然后每 10 秒触发一次 ???????ITrigger trigger = TriggerBuilder.Create() ???????????.WithIdentity("trigger1", "group1") ???????????.StartNow() ???????????.WithSimpleSchedule(x => x ???????????????.WithIntervalInSeconds(10) ???????????????.RepeatForever()) ???????????.Build(); ???????// 指示 quartz 使用触发器调度作业 ???????await scheduler.ScheduleJob(job, trigger);
完整代码
using System;using System.Collections.Specialized;using System.Threading.Tasks;using Quartz;using Quartz.Impl;using Quartz.Logging;namespace QuartzSampleApp{ ???public class Program ???{ ???????private static void Main(string[] args) ???????{ ???????????LogProvider.SetCurrentLogProvider(new ConsoleLogProvider()); ???????????// 异步执行 ???????????RunProgram().GetAwaiter().GetResult(); ???????} ???????private static async Task RunProgram() ???????{ ???????????try ???????????{ ???????????????// 从工厂获取 Scheduler 实例 ???????????????NameValueCollection props = new NameValueCollection ???????????????{ ???????????????????{ "quartz.serializer.type", "binary" } ???????????????}; ???????????????StdSchedulerFactory factory = new StdSchedulerFactory(props); ???????????????IScheduler scheduler = await factory.GetScheduler(); ???????????????// 启动 Scheduler 实例 ???????????????await scheduler.Start(); ???????????????// 定义作业,关联到 HelloJob ???????????????IJobDetail job = JobBuilder.Create<HelloJob>() ???????????????????.WithIdentity("job1", "group1") ???????????????????.Build(); ???????????????// 立即触发,然后每 10 秒触发一次 ???????????????ITrigger trigger = TriggerBuilder.Create() ???????????????????.WithIdentity("trigger1", "group1") ???????????????????.StartNow() ???????????????????.WithSimpleSchedule(x => x ???????????????????????.WithIntervalInSeconds(10) ???????????????????????.RepeatForever()) ???????????????????.Build(); ???????????????// 指示 quartz 使用触发器调度作业 ???????????????await scheduler.ScheduleJob(job, trigger); ???????????????// 停60秒看效果 ???????????????await Task.Delay(TimeSpan.FromSeconds(60)); ???????????????// 关闭程序前关闭 scheduler ???????????????await scheduler.Shutdown(); ???????????} ???????????catch (SchedulerException se) ???????????{ ???????????????await Console.Error.WriteLineAsync(se.ToString()); ???????????} ???????} ???????private class ConsoleLogProvider : ILogProvider ???????{ ???????????public Logger GetLogger(string name) ???????????{ ???????????????return (level, func, exception, parameters) => ???????????????{ ???????????????????if (level >= LogLevel.Info && func != null) ???????????????????{ ???????????????????????Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + level + "] " + func(), parameters); ???????????????????} ???????????????????return true; ???????????????}; ???????????} ???????????public IDisposable OpenNestedContext(string message) ???????????{ ???????????????throw new NotImplementedException(); ???????????} ???????????public IDisposable OpenMappedContext(string key, string value) ???????????{ ???????????????throw new NotImplementedException(); ???????????} ???????} ???} ???public class HelloJob : IJob ???{ ???????public async Task Execute(IJobExecutionContext context) ???????{ ???????????await Console.Out.WriteLineAsync("Greetings from HelloJob!"); ???????} ???}}
程序输出
程序启动后,输出以下内容:
[16:31:41] [Info] Using object serializer: Quartz.Simpl.BinaryObjectSerializer, Quartz[16:31:41] [Info] Initialized Scheduler Signaller of type: Quartz.Core.Scheduler SignalerImpl[16:31:41] [Info] Quartz Scheduler v.3.0.2.0 created.[16:31:41] [Info] RAMJobStore initialized.[16:31:41] [Info] Scheduler meta-data: Quartz Scheduler (v3.0.2.0) ‘QuartzScheduler‘ with instanceId ‘NON_CLUSTERED‘ ?Scheduler class: ‘Quartz.Core.QuartzScheduler‘ - running locally. ?NOT STARTED. ?Currently in standby mode. ?Number of jobs executed: 0 ?Using thread pool ‘Quartz.Simpl.DefaultThreadPool‘ - with 10 threads. ?Using job-store ‘Quartz.Simpl.RAMJobStore‘ - which does not support persistence. and is not clustered.[16:31:41] [Info] Quartz scheduler ‘QuartzScheduler‘ initialized[16:31:41] [Info] Quartz scheduler version: 3.0.2.0[16:31:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED started.Greetings from HelloJob!Greetings from HelloJob!Greetings from HelloJob!Greetings from HelloJob!Greetings from HelloJob!Greetings from HelloJob!Greetings from HelloJob![16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED shutting down.[16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED paused.[16:32:41] [Info] Scheduler QuartzScheduler_$_NON_CLUSTERED Shutdown complete.请按任意键继续. . .
Quartz.net 起步
原文地址:https://www.cnblogs.com/dongbeifeng/p/Quartz-net-3-quick-start.html