项目中需要用到QuartZ执行定时任务,在此记录一下学习过程。
Quartz安装
在VS2022中,通过Nuget包管理服务器托管器安装Quartz3.8.1 ,这是.net 6 依赖的最高版本。
创建定时器任务
1、创建QuartzConfigurator
新建QuartzConfiguratorExtensions类,用于注册触发器和任务,代码如下:
///
/// 添加任务和触发器
///
///
///
///
///
public static void AddJobAndTrigger(this IServiceCollectionQuartzConfigurator quartz, IConfiguration config) where T : IJob
{
// Use the name of the IJob as the appsettings.json key
string jobName = typeof(T).Name;
// Try and load the schedule from configuration
var configKey = $"Quartz:{jobName}";
var cronSchedule = config[configKey];
// Some minor validation
if (string.IsNullOrEmpty(cronSchedule))
{
throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}");
}
// register the job as before
var jobKey = new JobKey(jobName);
quartz.AddJob(opts => opts.WithIdentity(jobKey));
quartz.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(jobName + "-trigger")
.WithCronSchedule(cronSchedule)); // use the schedule from configuration
}
///
/// 添加任务和触发器(带参数传递)
///
///
///
///
/// 需要传递的参数
/// 默认通过 工作描述时传递参数
///
public static void AddJobAndTriggerWithParameter(this IServiceCollectionQuartzConfigurator quartz, IConfiguration config,
IDictionary? keyValuePairs = null, bool isJobDetailJobDataMap = true) where T : IJob
{
// Use the name of the IJob as the appsettings.json key
string jobName = typeof(T).Name;
// Try and load the schedule from configuration
var configKey = $"Quartz:{jobName}";
var cronSchedule = config[configKey];
// Some minor validation
if (string.IsNullOrEmpty(cronSchedule))
{
throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}");
}
// register the job as before
var jobKey = new JobKey(jobName);
if (keyValuePairs != null && isJobDetailJobDataMap)
{
switch (isJobDetailJobDataMap)
{
case true:
quartz.AddJob(opts => opts
.WithIdentity(jobKey)
.UsingJobData(new JobDataMap(keyValuePairs)));
quartz.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(jobName + "-trigger")
.WithCronSchedule(cronSchedule)); // use the schedule from configuration
break;
case false:
quartz.AddJob(opts => opts
.WithIdentity(jobKey));
quartz.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(jobName + "-trigger")
.WithCronSchedule(cronSchedule)
.UsingJobData(new JobDataMap(keyValuePairs))); // use the schedule from configuration
break;
}
}
else
{
quartz.AddJob(opts => opts
.WithIdentity(jobKey));
quartz.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity(jobName + "-trigger")
.WithCronSchedule(cronSchedule)); // use the schedule from configuration
}
}
2、在Program.cs 中注入服务
builder.Services.AddQuartz(q =>
{
创建计划单元(时间轴,载体)
//StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
//var scheduler = await schedulerFactory.GetScheduler();
//await scheduler.Start();
q.UseMicrosoftDependencyInjectionJobFactory();
// Register the job, loading the schedule from configuration
q.AddJobAndTrigger(builder.Configuration);
});
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
3、创建工作单元WorkerJob
新建类TestWorkerJob,并继承IJob,代码如下:
[PersistJobDataAfterExecution]//在执行完成后,保留JobDataMap数据
[DisallowConcurrentExecution]//不允许并发执行,即必须等待上次完成后才能执行下一次
public class TestWorkerJob : IJob
{
private readonly ILogger _logger;
public TestWorkerJob(ILogger logger)
{
_logger = logger;
}
public Task Execute(IJobExecutionContext context)
{
_logger.LogInformation(DateTime.Now +" --- Hello world!");
Task.Delay(50000);
Thread.Sleep(10000);
return Task.CompletedTask;
}
}
假如我们的定时任务,执行一次需要耗时比较久,而且后一次执行需要等待前一次完成,并且需要前一次执行的结果作为参考,那么就需要设置任务的任性。因为默认情况下,工作单元在每一次运行都是一个新的实例,相互之间独立运行,互不干扰。所以如果需要存在一定的关联,就要设置任务的特性,主要有两个,如下所示:
[PersistJobDataAfterExecut服务器托管ion]//在执行完成后,保留JobDataMap数据
[DisallowConcurrentExecution]//不允许并发执行,即必须等待上次完成后才能执行下一次
以上两个特性,只需要标记在任务对应的类上即可。
4、appsettings.json配置
在appsettings.json文件中添加一项Quartz,子项的必须与WorkerJob的名字保持一致,value是Cron表达式
{
"Quartz": {
"FromKingdeeWorkerJob": "0/5 * * * * ?"
}
}
然后,启动项目,就可以看到任务可以正常运行啦。
最后
最后附上学习链接,
.NET6+Quartz实现定时任务_.net6 quartz-CSDN博客
KSO – 在.NET6中项目级使用配置Quartz.NET定时任务,并使用IHostedService实现项目启动自动加载任务,常用的Corn表达式_net6 webapi 在配置中引入注入quartz-CSDN博客
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
每天学习一个Linux命令之nano 在Linux系统中,有许多文本编辑器可供选择,而nano是其中一款简洁易用的编辑器。本篇博客将详细介绍nano命令及其可用的选项,帮助读者更好地使用这个命令。 Nano命令简介 Nano是一个开源的、易于使用的、基于终端的…