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

Quartz安装

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

创建定时器任务

1、创建QuartzConfigurator

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

 /// <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 中注入服务

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,代码如下:

 [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表达式

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

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

最后

 最后附上学习链接,

.NET6+Quartz实现定时任务

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

到此这篇关于.net 6 配置QuartZ定时任务的文章就介绍到这了,更多相关.net 6 QuartZ定时任务内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部