c# quartz 动态创建任务 控制任务运行和停止 依赖注入

编写job

在Execute中添加定时任务的逻辑

   public class ScheduleJob : IJob
   {
       /// <summary>
       /// 
       /// </summary>
       /// <param name="context"></param>
       /// <returns></returns>
       public async Task Execute(IJobExecutionContext context)
       {
           Console.WriteLine($"{DateTime.Now.ToString("yy-MM-dd HH:mm:ss fff")},执行了Job");
           await Task.CompletedTask;
       }

   }

创建任务

通过IJobDetail来绑定job信息,ITrigger维护定时的间隔,StdSchedulerFactory 创建实际执行的任务。
通过scheduler这个实例对象控制任务启动和停止。
await scheduler.Start();
await scheduler.ScheduleJob(job, trigger);
await scheduler.Standby();

可以用 await StdSchedulerFactory.GetDefaultScheduler();获取默认的调度器,也可以自定义创建

IJobDetail job = JobBuilder.Create<TestJob>()
    .WithIdentity("TestJob", "myGroup")
    .Build();


ITrigger trigger = TriggerBuilder.Create()
    //.WithIdentity("TestJobTrigger", "myGroup")
    .WithCronSchedule("0 15 10 * * ?")
    .Build();


StdSchedulerFactory factory = new StdSchedulerFactory();
//创建任务调度器
IScheduler scheduler = await factory.GetScheduler();
//启动任务调度器
await scheduler.Start();

//将创建的任务和触发器条件添加到创建的任务调度器当中
await scheduler.ScheduleJob(job, trigger);

Console.WriteLine("任务调度器已启动,按任意键退出...");
//停止任务
//scheduler.Standby();

获取最近几次执行时间

//方式一
   CronExpression cronExpression = new CronExpression("0 15 10 * * ?");

   DateTimeOffset current = DateTime.Now;

   List<DateTime> result = new List<DateTime>();
   for (int i = 0; i < 5; i++)
   {
       var nextOffset = cronExpression.GetNextValidTimeAfter(current);

       var nextTime = nextOffset.Value.DateTime;
       result.Add(nextTime);
       current = nextOffset.Value;
   }


//方式二
var fireTimes = new List<DateTimeOffset>();

// 设置计算的起始时间,默认为当前时刻
var baseTime = DateTimeOffset.UtcNow;
DateTimeOffset? current = baseTime;

//根据Cron表达式构建触发器
// 注意:此处假设使用本地时间。如需特定时区,请使用`.InTimeZone`方法配置
ITrigger trigger = TriggerBuilder.Create()
    .WithCronSchedule("0 15 10 * * ?")
    .Build();


//  循环计算后续触发时间
for (int i = 0; i < 5; i++)
{
    current = trigger.GetFireTimeAfter(current);
    if (current == null) break; // 如果已经没有后续触发时间,则退出循环
    fireTimes.Add(current.Value);
}

依赖注入

  1. 添加一个JobFactory
 public class JobFactory : IJobFactory
 {
     private readonly IServiceProvider _serviceProvider;

     public JobFactory(IServiceProvider serviceProvider)
     {
         _serviceProvider = serviceProvider;
     }

     public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
     {
         return _serviceProvider.GetService<ScheduleJob>();
     }

     public void ReturnJob(IJob job)
     {
         var disposable = job as IDisposable;
         disposable?.Dispose();
     }
 }
  1. 在原先创建任务调度器的地方添加JobFactory
 //创建任务调度器
 IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();

//传入serviceProvider
 scheduler.JobFactory = new JobFactory(serviceProvider);
 await scheduler.Start();
 await scheduler.ScheduleJob(job, trigger);
 Console.WriteLine("任务调度器已启动,按任意键退出...");
  1. 在原先的Job内部使用依赖注入
public class ScheduleJob : IJob
{
    public static string ConfigKey { get; set; } = "Config";

    IScheduleTaskService scheduleTaskService;

    public ScheduleJob(IScheduleTaskService scheduleTaskService)
    {
        this.scheduleTaskService = scheduleTaskService;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task Execute(IJobExecutionContext context)
    {
        Console.WriteLine($"{DateTime.Now.ToString("yy-MM-dd HH:mm:ss fff")},执行了TestJob");
        await Task.CompletedTask;
    }

}

[参考]
C# 定时任务 Quartz.NET 的使用

posted @ 2026-01-05 15:36  Hey,Coder!  阅读(4)  评论(0)    收藏  举报