Quartz 任务调度

雪花飘落 / 2025-01-02 / 原文

Cron - 在线Cron表达式生成器 (ciding.cc)

 

/// <summary>
/// Job工厂
/// </summary>
public class JobFactory : IJobFactory
{
    /// <summary>
    /// 容器提供器
    /// </summary>
    private readonly IServiceProvider _serviceProvider;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="serviceProvider"></param>
    public JobFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    /// <summary>
    /// 返回IJob
    /// </summary>
    /// <param name="bundle"></param>
    /// <param name="scheduler"></param>
    /// <returns></returns>
    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        Type jobType = bundle.JobDetail.JobType;
        return _serviceProvider.GetService(jobType) as IJob;
    }

    /// <summary>
    /// 清理销毁IJob
    /// </summary>
    /// <param name="job"></param>
    public void ReturnJob(IJob job)
    {
        var disposable = job as IDisposable;
        disposable?.Dispose();
    }
}

 

 /// <summary>
 /// 启动定时调度任务
 /// </summary>
 public class JobHostedService : IHostedService
 {
     
     private readonly IServiceProvider _provider;
     private readonly JobService _jobService;

     /// <summary>
     /// 构造函数
     /// </summary>
     /// <param name="provider"></param>
     /// <param name="jobService"></param>
     public JobHostedService(IServiceProvider provider,JobService jobService)
     {
         _jobService = jobService;
         _provider = provider;
     }

     /// <summary>
     /// 执行定时任务
     /// </summary>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
     public async Task StartAsync(CancellationToken cancellationToken)
     {
         var warnServices = Container.Resolve<ITBWarnBLL>();
         List<TB_TasksQz> taskList = warnServices.GetWarnTasks();
         Log4Helper.Log.WriteLog($"程序服务开始:{SerializationHelper.SerializeJson(taskList)}", null, JHSC.Log.ELogType.Info);
         foreach (var item in taskList)
         {
             try
             {
                 var result = await _jobService.RunAsync(item);
                 if (result)
                 {
                     Log4Helper.Log.WriteLog($"任务启动成功:{SerializationHelper.SerializeJson(item)}", null, JHSC.Log.ELogType.Info);
                 }
             }
             catch (Exception ex)
             {
                 Log4Helper.Log.WriteLog($"任务启动失败:{ex.Message}", ex, JHSC.Log.ELogType.Error);
             }
         }
         await StopAsync(cancellationToken); //在项目查询运行的时候运行一次
     }

     /// <summary>
     /// 关闭任务
     /// </summary>
     /// <param name="cancellationToken"></param>
     /// <returns></returns>
     public Task StopAsync(CancellationToken cancellationToken)
     {
         return Task.CompletedTask;

     }
 }
  /// <summary>
  /// 任务调度服务,主要负责任务的运行和暂停
  /// </summary>
  public class JobService
  {
      private readonly ISchedulerFactory _schedulerFactory;
      private readonly JobFactory _jobFactory;

      /// <summary>
      /// 构造函数
      /// </summary>
      /// <param name="schedulerFactory"></param>
      /// <param name="jobFactory"></param>
      public JobService(ISchedulerFactory schedulerFactory, JobFactory jobFactory)
      {
          _schedulerFactory = schedulerFactory;
          _jobFactory = jobFactory;
      }

      /// <summary>
      /// 开始运行一个调度器
      /// </summary>
      /// <param name="task"></param>
      /// <returns></returns>
      public async Task<bool> RunAsync(TB_TasksQz task)
      {

          //1、通过调度工厂获得调度器
          var scheduler = await _schedulerFactory.GetScheduler();

          //2、创建一个触发器
          var trigger = JobTool.CreateTrigger(task);

          //3、创建任务
          IJobDetail jobDetail = JobTool.CreateWarnJobDetail(task);

          //4、写入 Job 实例工厂 解决 Job 中取 ioc 对象
          scheduler.JobFactory = _jobFactory;

          //5、将触发器和任务器绑定到调度器中
          await scheduler.ScheduleJob(jobDetail, trigger);

          //6、开启调度器
          await scheduler.Start();

          return await Task.FromResult(true);
      }

      /// <summary>
      /// 关闭调度器
      /// </summary>
      /// <param name="task"></param>
      /// <returns></returns>
      public async Task<bool> CloseAsync(TB_TasksQz task)
      {
          Log4Helper.Log.WriteLog($"关闭调度器 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
          IScheduler scheduler = await _schedulerFactory.GetScheduler();
          var jobKey = new JobKey(task.TaskId, task.JobGroup);
          if (jobKey == null)
          {
              Log4Helper.Log.WriteLog($"未找到任务 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
              return false;
          }
          var triggers = await scheduler.GetTriggersOfJob(jobKey);
          var trigger = triggers?.Where(x => x.JobKey.Name == task.TaskId).FirstOrDefault();
          if (trigger == null)
          {
              Log4Helper.Log.WriteLog($"未找到触发器 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
              return false;
          }
          await scheduler.PauseTrigger(trigger.Key);
          await scheduler.UnscheduleJob(trigger.Key);// 移除触发器
          await scheduler.DeleteJob(trigger.JobKey);
          Console.WriteLine("关闭成功:" + task.TaskId);
          return await Task.FromResult(true);
      }

      /// <summary>
      /// 暂停调度器
      /// </summary>
      /// <param name="task"></param>
      /// <returns></returns>
      public async Task<bool> StopAsync(TB_TasksQz task)
      {
          Log4Helper.Log.WriteLog($"暂停调度器 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
          IScheduler scheduler = await _schedulerFactory.GetScheduler();
          var jobKey = new JobKey(task.TaskId, task.JobGroup);
          await scheduler.PauseJob(jobKey);
          return await Task.FromResult(true);
      }

      /// <summary>
      /// 恢复调度器
      /// </summary>
      /// <param name="task"></param>
      /// <returns></returns>
      public async Task<bool> ResumeJob(TB_TasksQz task)
      {
          Log4Helper.Log.WriteLog($"暂停调度器 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
          IScheduler scheduler = await _schedulerFactory.GetScheduler();
          var jobKey = new JobKey(task.TaskId, task.JobGroup);
          var isExist = await scheduler.CheckExists(jobKey);
          if (!isExist)
          {
              Log4Helper.Log.WriteLog($"未找到任务 [{task.TaskId}_{task.JobGroup}]:", null, JHSC.Log.ELogType.Info);
              return false;
          }
          await scheduler.ResumeJob(jobKey);
          return await Task.FromResult(true);
      }

      /// <summary>
      /// 修改触发器
      /// </summary>
      /// <param name="task"></param>
      /// <returns></returns>
      public async Task<bool> EditTrigger(TB_TasksQz task)
      {
          IScheduler scheduler = await _schedulerFactory.GetScheduler();
          TriggerKey triggerKey = new TriggerKey(task.TaskId, task.JobGroup);
          ITrigger trigger = await scheduler.GetTrigger(triggerKey);
          if (trigger != null)
          {
              trigger = JobTool.CreateTrigger(task);
              await scheduler.RescheduleJob(triggerKey, trigger);
          }
          return await Task.FromResult(true);
      }
  }
 /// <summary>
 ///  工具
 /// </summary>
 public class JobTool
 {

     /// <summary>
     /// 创建SimpleTrigger触发器(简单触发器)
     /// </summary>
     /// <param name="tasksQz"></param>
     /// <returns></returns>
     public static ITrigger CreateTrigger(TB_TasksQz tasksQz)
     {
         if (tasksQz.BeginTime == null)
         {
             tasksQz.BeginTime = DateTime.Now;
         }
         if (tasksQz.EndTime == null)
         {
             tasksQz.EndTime = DateTime.Now.AddYears(1);
         }
         if (!string.IsNullOrEmpty(tasksQz.Cron))
         {
             return CreateCronTrigger(tasksQz);
         }
         return CreateSimpleTrigger(tasksQz);
     }

     /// <summary>
     /// 创建任务
     /// </summary>
     /// <param name="task"></param>
     /// <returns></returns>
     public static IJobDetail CreateWarnJobDetail(TB_TasksQz task)
     {
         var jobDetail = JobBuilder.Create<WarnJob>()
                         .WithIdentity(task.TaskId, task.JobGroup)
                         .Build();
         jobDetail.JobDataMap.Add("JobParams", task.JobParams);
         return jobDetail;
     }

     /// <summary>
     /// 创建SimpleTrigger触发器(简单触发器)
     /// </summary>
     /// <param name="tasksQz"></param>
     /// <returns></returns>
     private static ITrigger CreateSimpleTrigger(TB_TasksQz tasksQz)
     {
         if (tasksQz.RunTimes > 0)
         {
             ITrigger trigger = TriggerBuilder.Create()
             .WithIdentity(tasksQz.TaskId, tasksQz.JobGroup)
             .StartAt(tasksQz.BeginTime.Value)
             .EndAt(tasksQz.EndTime.Value)
             .WithSimpleSchedule(x =>x.WithIntervalInSeconds(tasksQz.IntervalSecond)
             .WithRepeatCount(tasksQz.RunTimes))
             .Build();
             return trigger;
         }
         else
         {
             ITrigger trigger = TriggerBuilder.Create()
             .WithIdentity(tasksQz.TaskId, tasksQz.JobGroup)
             .StartAt(tasksQz.BeginTime.Value)
             .EndAt(tasksQz.EndTime.Value)
             .WithSimpleSchedule(x =>x.WithIntervalInSeconds(tasksQz.IntervalSecond)
             .RepeatForever())
             .Build();
             return trigger;
         }
     }

     /// <summary>
     /// 创建类型Cron的触发器
     /// </summary>
     /// <param name="tasksQz"></param>
     /// <returns></returns>
     private static ITrigger CreateCronTrigger(TB_TasksQz tasksQz)
     {
         ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(tasksQz.TaskId, tasksQz.JobGroup)
                .StartAt(tasksQz.BeginTime.Value)//开始时间
                .EndAt(tasksQz.EndTime.Value)//结束数据
                .WithCronSchedule(tasksQz.Cron)//指定cron表达式
                .Build();
         return trigger;
     }

 }
 /// <summary>
 /// 预警
 /// </summary>
 [DisallowConcurrentExecution]
 public class WarnJob : IJob
 {
     /// <summary>
     /// 执行
     /// </summary>
     /// <param name="context"></param>
     /// <returns></returns>
     public Task Execute(IJobExecutionContext context)
     {
         JobDataMap dataMap = context.JobDetail.JobDataMap;
         string jobParams = dataMap.GetString("JobParams");
         if (!string.IsNullOrEmpty(jobParams))
         {
             var warnServices = Container.Resolve<ITBWarnBLL>();
             warnServices.RemindWarn(SerializationHelper.DeserializeJson<TB_Warn>(jobParams));
             Log4Helper.Log.WriteLog($"任务执行完成:{jobParams}", null, JHSC.Log.ELogType.Info);
         }
         return Task.CompletedTask;
     }
 }