.net 6 配置QuartZ定时任务

项目中需要用到QuartZ执行定时任务,在此记录一下学习过程。

Quartz安装

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

创建定时器任务

1、创建QuartzConfigurator

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

cs 复制代码
 /// <summary>
 /// 添加任务和触发器
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="quartz"></param>
 /// <param name="config"></param>
 /// <exception cref="Exception"></exception>
 public static void AddJobAndTrigger<T>(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<T>(opts => opts.WithIdentity(jobKey));

     quartz.AddTrigger(opts => opts
         .ForJob(jobKey)
         .WithIdentity(jobName + "-trigger")
         .WithCronSchedule(cronSchedule)); // use the schedule from configuration
 }

 /// <summary>
 /// 添加任务和触发器(带参数传递)
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="quartz"></param>
 /// <param name="config"></param>
 /// <param name="keyValuePairs">需要传递的参数</param>
 /// <param name="IsTriggerJobDataMap">默认通过 工作描述时传递参数</param>
 /// <exception cref="Exception"></exception>
 public static void AddJobAndTriggerWithParameter<T>(this IServiceCollectionQuartzConfigurator quartz, IConfiguration config,
     IDictionary<string, object>? 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<T>(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<T>(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<T>(opts => opts
                      .WithIdentity(jobKey));
         quartz.AddTrigger(opts => opts
                .ForJob(jobKey)
                .WithIdentity(jobName + "-trigger")
                .WithCronSchedule(cronSchedule)); // use the schedule from configuration
     }
 }

2、在Program.cs 中注入服务

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<FromKingdeeWorkerJob>(builder.Configuration);
});
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);

3、创建工作单元WorkerJob

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

cs 复制代码
 [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//不允许并发执行,即必须等待上次完成后才能执行下一次

以上两个特性,只需要标记在任务对应的类上即可。

4、appsettings.json配置

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

cs 复制代码
{
  "Quartz": {
    "FromKingdeeWorkerJob": "0/5 * * * * ?"
  }
}

然后,启动项目,就可以看到任务可以正常运行啦。

最后

最后附上学习链接,

.NET6+Quartz实现定时任务_.net6 quartz-CSDN博客

KSO - 在.NET6中项目级使用配置Quartz.NET定时任务,并使用IHostedService实现项目启动自动加载任务,常用的Corn表达式_net6 webapi 在配置中引入注入quartz-CSDN博客

相关推荐
牛哇网络工作室4 小时前
UnityHDRP写实数字人全流程基础5—语音输入和语音识别
android·unity·c#·游戏引擎·aigc·语音识别·xcode
zlinear数据采集卡15 小时前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
深澈Vincel17 小时前
我用 C# + WebView2 做了一个针对“流氓软件”的“一键清理工具“:架构实践与踩坑记录
c#
zlinear数据采集卡18 小时前
数据采集卡从入门到精通(7):流水线型ADC——级级接力,高速与高精的平衡术
开发语言·arm开发·嵌入式硬件·fpga开发·c#
kingwebo'sZone19 小时前
C# 根据公式计算的方法
开发语言·c#
阿部多瑞 ABU20 小时前
告别手工核图:基于 .NET + MuPDFCore 的 CAD 等轴测 PDF 材料表提取与新旧版本对比实战
后端·算法·ui·pdf·c#
条形码D20 小时前
DRG综合管理分析系统-目前已经支持CHS-DRG3.0
c#·drg·3.0分组器·drg分组器·chs-drg3.0分组器
Alex Gram2 天前
数据库同步工具PanguSync图文教程
java·mysql·postgresql·sqlserver·c#·数据库同步软件·数据库同步工具
头茬韭菜2 天前
第 10 篇:「Fluss 实战案例集」—— 完整解决方案与最佳实践
c#·linq·fluss
淡海水2 天前
01-05-运行时-JIT优化全景-内联去虚拟化边界检查消除
windows·c#·虚拟化·jit·内联·边界检查消除