首先奉上quartz官网,官网内附有此框架的各个版本以及详细教程的方法讲解,可自行了解
https://www.quartz-scheduler.net/
第一步:添加程序集,解决方案——右键项目——管理NuGet程序包
搜索quartz,并下载,如下图,此处我当前下载的版本是v3.0.6
下载完成后会发现项目引用里面多了几个引用,并且多了一个packages.config文件 此时第一步结束
由于后续需要用到打印log日志,我需要用到log4net,所以我用相同的方法添加了引用,并进行了app.config文件的配置
第二步:了解Quartz一些关键接口和类
Quartz API的关键接口和类是:
- IScheduler - 与调度程序交互的主要API。
- IJob - 由您希望由调度程序执行的组件实现的接口。
- IJobDetail - 用于定义Jobs的实例。
- ITrigger - 一个组件,用于定义执行给定作业的计划。
- JobBuilder - 用于定义/构建JobDetail实例,用于定义Jobs的实例。
- TriggerBuilder - 用于定义/构建触发器实例。
一个调度程序的生命周期是由它为界的创作,通过SchedulerFactory和其关断()方法的调用。创建后,可以使用IScheduler接口添加,删除和列出作业和触发器,以及执行其他与调度相关的操作(例如暂停触发器)。但是,在使用Start()方法启动调度程序之前,调度程序实际上不会对任何触发器执行(执行作业)
第三步:新建一个windows服务,接着我定义了一个接口,并且新建两个文件夹,一个Jobs,一个Tiggers(这里是考虑到一个项目里面可能有多个定时任务,而每个定时任务的触发时间都不同)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServiceDemo
{
public interface IServiceTrigger
{
void RunAsync();
void Shutdown();
}
}
using log4net;
using MyServiceDemo;
using MyServiceDemo.Triggers;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace MyTaskDemo
{
public partial class Service1 : ServiceBase
{
ILog log = LogManager.GetLogger(typeof(Service1));
IServiceTrigger clockTrigger;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
log.Info("begin...");
clockTrigger = new ClockTrigger();
clockTrigger.RunAsync();
}
protected override void OnStop()
{
}
}
}
第四点:举个栗子,我这里需要定时打印一个日志,然后我在Triggers文件夹里面添加了一个clockTrigger类用于实现接口,当服务开启时,它会去访问我定义好的RunAsync(),同样的结束的时候,会去访问我定义好的Shutdown()。这里对windows服务不了解的需要先去了解一下,然后在Jobs文件夹添加了一个clockJob.cs
ClockTrigger类里面是用于定义具体触发的时间以及环境,只有到时间才会去实现clockJob类里面的内容
using log4net;
using MyServiceDemo.Jobs;
using MyTaskDemo;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServiceDemo.Triggers
{
public class ClockTrigger : IServiceTrigger
{
ILog log = LogManager.GetLogger(typeof(ClockTrigger));
IScheduler scheduler;
public static DateTime utcTime1 = new DateTime(2018, 8, 28, 14, 48, 0);
DateTimeOffset utcTime2 = DateTime.SpecifyKind(utcTime1, DateTimeKind.Utc);
public ClockTrigger()
{
}
public async void RunAsync()
{
try
{
log.Info("Start1...");
// construct a scheduler factory
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" }
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
// get a scheduler
IScheduler sched = await factory.GetScheduler();
await sched.Start();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<ClockJob>()
.WithIdentity("clockJob", "group1")
.Build();
// 在特定时刻构建触发器,不重复
//ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create()
// .WithIdentity("clockTrigger", "group2")
// .StartAt(utcTime1) // some Date
// .ForJob("clockJob", "group1") // identify job with name, group strings
// .Build();
//log.Info(utcTime1);
//在特定时刻构建触发器,然后每十秒重复十次:
ISimpleTrigger trigger = (ISimpleTrigger)TriggerBuilder.Create()
.WithIdentity("clockTrigger", "group1")
.StartAt(utcTime1) // if a start time is not given (if this line were omitted), "now" is implied
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.WithRepeatCount(10)) // note that 10 repeats will give a total of 11 firings
.ForJob("clockJob", "group1") // identify job with handle to its JobDetail itself
.Build();
// //构建一个触发器,将在未来五分钟内触发
// trigger = (ISimpleTrigger)TriggerBuilder.Create()
// .WithIdentity("trigger5", "group1")
// .StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute)) // use DateBuilder to create a date in the future
// .ForJob(job) // identify job with its JobKey
// .Build();
// //构建一个现在将触发的触发器,然后每五分钟重复一次,直到22:00:
// trigger = (ISimpleTrigger)TriggerBuilder.Create()
// .WithIdentity("trigger7", "group1")
// .WithSimpleSchedule(x => x
// .WithIntervalInMinutes(5)
// .RepeatForever())
// .EndAt(DateBuilder.DateOf(22, 0, 0))
// .Build();
// log.Info("Start3...");
// //构建一个触发器,在下一个小时的顶部触发,然后每2小时重复一次,永远:
// trigger = (ISimpleTrigger)TriggerBuilder.Create()
// .WithIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group
// .StartAt(DateBuilder.EvenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00"))
// .WithSimpleSchedule(x => x
// .WithIntervalInHours(2)
// .RepeatForever())
// // note that in this example, 'forJob(..)' is not called
//// - which is valid if the trigger is passed to the scheduler along with the job
// .Build();
await sched.ScheduleJob(job, trigger);
}
catch (Exception)
{
throw;
}
}
public void Shutdown()
{
throw new NotImplementedException();
}
}
}
using log4net;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyServiceDemo.Jobs
{
public class ClockJob : IJob
{
ILog log = LogManager.GetLogger(typeof(ClockJob));
//实现接口
public async Task Execute(IJobExecutionContext context)
{
log.Info("定时任务开始被触发");
await Console.Out.WriteLineAsync("HelloJob is executing.");
log.Info("定时任务被触发结束");
}
}
}
当开启服务后,log日志里面会打印一系列日志,当出现以下几句日志的时候,至少说明你的Quartz开始跑起来了
根据ClockTrigger里面设置的时间,任务应该是当天14::4执行,每十秒重复十次,共11次打印日志
此时ClockJob里的日志以及被执行完成,一个简单的定时任务实例就完成啦