【.Net 6.0】使用QuartZ创建定时任务

.net 6 配置QuartZ定时任务的过程

这篇文章主要介绍了.net 6 配置QuartZ定时任务的过程,在VS2022中,通过Nuget包管理器安装Quartz 3.8.1 ,这是.net 6 依赖的最高版本,在此记录学习一下,需要的朋友可以参考下

1.Quartz安装

在VS2022中,通过Nuget包管理器安装Quartz 3.9.0 ,这是.net 6 依赖的最高版本。

2.创建定时器任务

a.创建QuartzConfigurator

新建QuartzConfiguratorExtensions类,用于注册触发器和任务,代码如下:

using Microsoft.Extensions.Configuration;
using Quartz;

namespace testmanage.Common;

public static class QuartzConfiguratorExtension
{
    /// <summary>
    /// 添加任务和触发器
    /// </summary>
    /// <typeparam name="T">要添加的任务类型,必须实现 IJob 接口</typeparam>
    /// <param name="quartz">Quartz 服务配置接口</param>
    /// <param name="config">应用程序配置,用于读取 Cron 表达式</param>
    /// <exception cref="Exception">当配置中找不到对应的 Cron 表达式时抛出异常</exception>
    public static void AddJobAndTrigger<T>(this IServiceCollectionQuartzConfigurator quartz, IConfiguration config) where T : IJob
    {
        // 使用 IJob 的名称作为配置键
        string jobName = typeof(T).Name;
        // 从配置中加载任务调度时间
        var configKey = $"Quartz:{jobName}";
        var cronSchedule = config[configKey];
        // 验证 Cron 表达式是否存在
        if (string.IsNullOrEmpty(cronSchedule))
        {
            throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}");
        }
        // 注册 Job 和对应的触发器
        var jobKey = new JobKey(jobName);
        quartz.AddJob<T>(opts => opts.WithIdentity(jobKey));
        quartz.AddTrigger(opts => opts
            .ForJob(jobKey)
            .WithIdentity(jobName + "-trigger")
            .WithCronSchedule(cronSchedule)); // 使用从配置中读取的调度时间
    }

    /// <summary>
    /// 添加任务和触发器(带参数传递)
    /// </summary>
    /// <typeparam name="T">要添加的任务类型,必须实现 IJob 接口</typeparam>
    /// <param name="quartz">Quartz 服务配置接口</param>
    /// <param name="config">应用程序配置,用于读取 Cron 表达式</param>
    /// <param name="keyValuePairs">需要传递给任务的参数键值对</param>
    /// <param name="isJobDetailJobDataMap">指示参数是否应传递给 JobDetail</param>
    /// <exception cref="Exception">当配置中找不到对应的 Cron 表达式时抛出异常</exception>
    public static void AddJobAndTriggerWithParameter<T>(this IServiceCollectionQuartzConfigurator quartz, IConfiguration config,
        IDictionary<string, object>? keyValuePairs = null, bool isJobDetailJobDataMap = true) where T : IJob
    {
        // 使用 IJob 的名称作为配置键
        string jobName = typeof(T).Name;
        // 从配置中加载任务调度时间
        var configKey = $"Quartz:{jobName}";
        var cronSchedule = config[configKey];
        // 验证 Cron 表达式是否存在
        if (string.IsNullOrEmpty(cronSchedule))
        {
            throw new Exception($"No Quartz.NET Cron schedule found for job in configuration at {configKey}");
        }
        // 注册 Job 和对应的触发器
        var jobKey = new JobKey(jobName);
        if (keyValuePairs != null && isJobDetailJobDataMap)
        {
            // 根据 isJobDetailJobDataMap 的值决定参数传递给 JobDetail 或触发器
            switch (isJobDetailJobDataMap)
            {
                case true:
                    quartz.AddJob<T>(opts => opts
                          .WithIdentity(jobKey)
                          .UsingJobData(new JobDataMap(keyValuePairs)));
                    quartz.AddTrigger(opts => opts
                           .ForJob(jobKey)
                           .WithIdentity(jobName + "-trigger")
                           .WithCronSchedule(cronSchedule));
                    break;

                case false:
                    quartz.AddJob<T>(opts => opts.WithIdentity(jobKey));
                    quartz.AddTrigger(opts => opts
                           .ForJob(jobKey)
                           .WithIdentity(jobName + "-trigger")
                           .WithCronSchedule(cronSchedule)
                           .UsingJobData(new JobDataMap(keyValuePairs)));
                    break;
            }
        }
        else
        {
            quartz.AddJob<T>(opts => opts.WithIdentity(jobKey));
            quartz.AddTrigger(opts => opts
                   .ForJob(jobKey)
                   .WithIdentity(jobName + "-trigger")
                   .WithCronSchedule(cronSchedule));
        }
    }
}
b.在Program.cs 中注入服务
builder.Services.AddQuartz(q =>
{
    q.UseMicrosoftDependencyInjectionJobFactory();
    q.AddJobAndTrigger<TestWorkerJob>(builder.Configuration);
});
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
c.创建工作单元WorkerJob

新建类TestWorkerJob,并继承IJob,代码如下:

[PersistJobDataAfterExecution]//在执行完成后,保留JobDataMap数据
[DisallowConcurrentExecution]//不允许并发执行,即必须等待上次完成后才能执行下一次
public class TestWorkerJob : IJob
{
    private readonly ILogger<TesteWorkerJob> _logger;
    public TestWorkerJob(ILogger<TestWorkerJob> logger)
    { 
        _logger = logger;
    }
    public Task Execute(IJobExecutionContext context)
    {
        _logger.LogInformation(DateTime.Now +" --- Hello world!");
        Task.Delay(50000);
        Thread.Sleep(10000);
        return Task.CompletedTask;
    }
}

假如我们的定时任务,执行一次需要耗时比较久,而且后一次执行需要等待前一次完成,并且需要前一次执行的结果作为参考,那么就需要设置任务的任性。因为默认情况下,工作单元在每一次运行都是一个新的实例,相互之间独立运行,互不干扰。所以如果需要存在一定的关联,就要设置任务的特性,主要有两个,如下所示:

[PersistJobDataAfterExecution]//在执行完成后,保留JobDataMap数据
[DisallowConcurrentExecution]//不允许并发执行,即必须等待上次完成后才能执行下一次
以上两个特性,只需要标记在任务对应的类上即可。

d.appsettings.json配置

在appsettings.json文件中添加一项Quartz,子项的必须与WorkerJob的名字保持一致,value是Cron表达式

{
  "Quartz": {
    "FromKingdeeWorkerJob": "0/5 * * * * ?"
  }
}

参考自:https://www.jb51.net/aspnet/319874b5e.htm

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值