c#学习笔记-------------------Quartz.NET任务调度框架

发布时间 2023-11-10 15:22:00作者: 三流程序媛

Quartz.NET任务调度框架

 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。

Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。

整合了 Quartz.NET的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。

注:支持 .NET Core/.NET Standard 2.0 和 .NET 框架 4.6.1 及更晚版本。

使用方法

创建一个类, 它继承于IJob接口, 实现了Execute方法, 任务就是输出一个字符串

public class TestJob : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        await Console.Out.WriteLineAsync($"{DateTime.Now}:Hello!");
    }
}

创建任务

//创建一个工作
IJobDetail job = JobBuilder.Create<TestJob>()
 .WithIdentity("TestJob", "Test")
.Build();

配置任务的参数

任务配置一个触发条件及相关的参数。当该配置的参数一旦达到了条件, 上面的任务将被触发

//创建一个触发条件
ITrigger trigger = TriggerBuilder.Create()
   .WithIdentity("TestJobTrigger", "Test")
   .WithSimpleSchedule(x =>
   {
       x.WithIntervalInSeconds(3).RepeatForever();
   })
   .Build();

创建一个任务调度器, 将任务和配置参数添加到调度器当中。

StdSchedulerFactory factory = new StdSchedulerFactory();
//创建任务调度器
IScheduler scheduler = await factory.GetScheduler();
//启动任务调度器
scheduler.Start();  
 
//将创建的任务和触发器条件添加到创建的任务调度器当中
scheduler.ScheduleJob(job, trigger);

实际效果

 

配置说明

  • 特定时间触发,重复触发,单次触发, 触发次数,开始时间, 结束时间。 这些在框架当中都有该功能

 

触发器表达式 ,例如: 每周一上午, 或每周一、周三、周五等等

下面是一些表达式及其含义的示例

示例 1 - 创建每 5 分钟触发一次的触发器的表达式

 

"0 0/5 * * * ?"

示例 2 - 创建每 5 分钟触发一次的触发器的表达式,在分钟后 10 秒(即上午 10:00:10、上午 10:05:10 等)。

"10 0/5 * * * ?"

示例 3 - 用于创建触发器的表达式,该触发器在每个星期三和周五的 10:30、11:30、12:30 和 13:30 触发。

"0 30 10-13 ? * WED,FRI"

示例 4 - 创建触发器的表达式,在每月 5 日到 20 日上午 8 点到上午 10 点之间每半小时触发一次。请注意,触发器不会于上午 10:00 触发,只是在 8:00、8:30、9:00 和 9:30

快速搭建一个Quartz

第一步,引入程序包

新建一个Demo项目并且引用以下程序包

  • Install-Package Quartz
  • Install-Package Common.Logging.Log4Net1211
  • Install-Package log4net
  • Install-Package Topshelf
  • Install-Package Topshelf.Log4Net

第二步,实现IJob

TestJob.cs 实现IJob,在Execute方法里编写要处理的业务逻辑,系统就会按照Quartz的配置,定时处理。

using log4net;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuartzDemo.QuartzJobs
{
    public sealed class TestJob : IJob
    {
        private readonly ILog _logger = LogManager.GetLogger(typeof(TestJob));

        public void Execute(IJobExecutionContext context)
        {
            _logger.InfoFormat("TestJob测试");
        }
    }
}

第三步,创建任务调度类

public class TaskCommon
{
    public static Task TaskStartNew(Action action, bool isThrow = false)
    {
        return Task.Factory.StartNew(action).ContinueWith(delegate(Task t)
        {
            try
            {
                if (t.Exception != null && t.Exception.InnerException != null)
                {
                    MessageCommon.AddMessage(t.Exception.InnerException);
                }
            }
            catch
            {
            }
            finally
            {
                if (t.Exception != null && t.Exception.InnerException != null && isThrow)
                {
                    throw t.Exception.InnerException;
                }
            }
        });
    }
}

第三步,任务管理器

public class QuartzCommon
{
    public static void CreateJob(IScheduler scheduler, Type type, string cronTime)
    {
        IJobDetail jobDetail = JobBuilder.Create(type).WithIdentity(type.ToString()).Build();
        ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create().WithIdentity(type.ToString()).StartNow()
            .WithCronSchedule(cronTime)
            .Build();
        scheduler.ScheduleJob(jobDetail, trigger);
    }

    public static bool IsSameTime(string cron, DateTime dt)
    {
        if (dt.Second != 0)
        {
            dt = dt.AddSeconds(-1 * dt.Second);
        }
        CronExpression cronExpression = new CronExpression(cron);
        if (!cronExpression.IsSatisfiedBy(dt))
        {
            DateTimeOffset? nextValidTimeAfter = cronExpression.GetNextValidTimeAfter(dt);
            if (nextValidTimeAfter.HasValue && nextValidTimeAfter.Value.ToLocalTime().Year == dt.Year && nextValidTimeAfter.Value.ToLocalTime().Month == dt.Month && nextValidTimeAfter.Value.ToLocalTime().Day == dt.Day && nextValidTimeAfter.Value.ToLocalTime().Hour == dt.Hour && nextValidTimeAfter.Value.ToLocalTime().Minute == dt.Minute)
            {
                return true;
            }
            return false;
        }
        return true;
    }

    public static bool IsSameTime(string cron, List<DateTime> dt)
    {
        foreach (DateTime item in dt)
        {
            if (IsSameTime(cron, item))
            {
                return true;
            }
        }
        return false;
    }
}

第三步,注册任务

 TaskCommon.TaskStartNew(delegate { 
     ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
        IScheduler scheduler = schedulerFactory.GetScheduler();
     QuartzCommon.CreateJob(scheduler, typeof(TestJob), "0 * * * * ? ");
     });

 

更多学习资料:

https://www.cnblogs.com/Vincent-yuan/p/10903355.html

https://www.cnblogs.com/pingming/p/4999228.html