一、依赖下载
Quartz
二、基础使用
2.1 创建任务
internal class SendMessageJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() =>
{
Console.WriteLine("hello:" + DateTime.Now);
});
}
}
2.2 任务初始化
public async static Task Init()
{
#region 创建单元
var factory = new StdSchedulerFactory();
IScheduler task = await factory.GetScheduler();
await task.Start();
#endregion
// job 作业
IJobDetail jobDetail = JobBuilder.Create<SendMessageJob>()
.WithIdentity("sendMessageJob","group1")
.WithDescription("this is send message job")
.Build();
// trigger 事件策略
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("sendMessageTriageer", "group")
.StartNow()
.WithSimpleSchedule(w=>w.WithIntervalInSeconds(1).WithRepeatCount(3))
.Build();
// 将事件策略和作业承载到单元上
await task.ScheduleJob(jobDetail, trigger);
}
2.3 任务调度
MyFunction.Init().GetAwaiter().GetResult();
2.4 使用演示
注意,实际运行次数会比要求次数多一次
三、更多细节
3.1 参数传递
有 JobDetail
、Trigger
、Merged
三种方式
3.1.1 参数提供
using Quartz;
using Quartz.Impl;
using quartz_01.CustomerJob;
namespace quartz_01
{
public class MyFunction
{
public async static Task Init()
{
#region 创建单元
var factory = new StdSchedulerFactory();
IScheduler task = await factory.GetScheduler();
await task.Start();
#endregion
// job 作业
IJobDetail jobDetail = JobBuilder.Create<SendMessageJob>()
.WithIdentity("sendMessageJob","group1")
.WithDescription("this is send message job")
.Build();
// 传入参数
jobDetail.JobDataMap.Add("user1","zhangsan");
jobDetail.JobDataMap.Add("user2", "lisi");
jobDetail.JobDataMap.Add("year", DateTime.Now.Year);
// trigger 事件策略
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("sendMessageTriageer", "group")
.StartNow()
.WithSimpleSchedule(w=>w.WithIntervalInSeconds(1))
.Build();
// 传入参数
trigger.JobDataMap.Add("user3", "zhangsan");
trigger.JobDataMap.Add("user4", "lisi");
trigger.JobDataMap.Add("year", DateTime.Now.Year + 1);
// 将事件策略和作业承载到单元上
await task.ScheduleJob(jobDetail, trigger);
}
}
}
3.1.2 参数接收
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace quartz_01.CustomerJob
{
internal class SendMessageJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() =>
{
Object v1 = context.JobDetail.JobDataMap.Get("user1");
string v2 = context.JobDetail.JobDataMap.GetString("user2");
int y1 = context.JobDetail.JobDataMap.GetInt("year");
Object v3 = context.Trigger.JobDataMap.Get("user3");
string v4 = context.Trigger.JobDataMap.GetString("user4");
int y2 = context.Trigger.JobDataMap.GetInt("year");
// 此方法也可取值,当JobDetail和Trigger都存在值时,取后者值覆盖
// 若两者只有一个有值,则取有值的那个
int y3 = context.MergedJobDataMap.GetInt("year");
Console.WriteLine("------- JobDetail --------");
Console.WriteLine(v1);
Console.WriteLine(v2);
Console.WriteLine(y1);
Console.WriteLine("------- Trigger --------");
Console.WriteLine(v3);
Console.WriteLine(v4);
Console.WriteLine(y2);
Console.WriteLine("------- Merged --------");
Console.WriteLine(y3);
});
}
}
}
3.1.3 效果演示
3.1.4 上一次结果为下一次参数
需要添加特性[PersistJobDataAfterExecution]
和调用put
方法
效果演示如下:
3.2 此次任务执行完毕后才可执行下次
3.2.1 当前问题
若此次任务还未执行完毕,就去执行下一次,会导致上一次传递的值失败
如,现在程序每1秒执行一次定时任务,而执行一次需要的时间为3秒,如何需要将上一次的值作为参数传递给下一次,将会传递失败
3.2.2 解决策略
在类上添加特性 [DisallowConcurrentExecution]
3.2.3 效果演示
JobDetail
中的 year
每次执行后都会加一,如图修改成功
3.3 时间策略
3.3.1 SimpleTriggle
从什么时候开始,间隔多久时间执行重复操作,可以限制最大次数
3.3.2 Cron
表达式的方式,可以灵活定制时间规则
可以根据需在线生成:在线Cron表达式生成器 (qqe2.com)