首页 > 其他分享 >Quartz 任务调度

Quartz 任务调度

时间:2025-01-21 14:35:34浏览次数:1  
标签:触发 Quartz 15 10 await 调度 scheduler 任务调度

Quartz.NET 是一个功能强大的开源任务调度库,广泛应用于 .NET 平台,用于定时执行任务。无论是简单的定时任务,还是复杂的调度需求,Quartz.NET 都能轻松应对。

官网:http://www.quartz-scheduler.net/

使用场景

  • 定时发送邮件:例如,每天定时发送报告邮件。
  • 定时备份数据库:例如,每天凌晨自动备份数据库。
  • 定时生成报表:例如,每月初生成上个月的销售报表。
  • 定时清理缓存:例如,每隔一段时间清理过期缓存。

主要组件

  1. Scheduler(调度器) :负责触发任务的核心组件。
  2. Job(任务) :执行特定操作的类,必须实现 IJob​ 接口。
  3. Trigger(触发器) :定义任务的执行时间。常见的触发器有 SimpleTrigger​(简单重复间隔)和 CronTrigger​(基于 cron 表达式的复杂调度)。
  4. JobDetail(任务详情) :包含任务执行所需的所有信息,如任务类和关联的作业数据。

基本用法

通过 NuGet 安装

  1. 打开 Visual Studio 并加载你的项目。
  2. 右键点击项目名称,选择“管理 NuGet 包”。
  3. 在 NuGet 包管理器中搜索“Quartz”,选择合适的版本,点击“安装”。

实现任务类

首先,创建一个实现了 IJob 接口的类。该接口包含 Execute 方法,任务运行时会调用此方法。

using Quartz;
using System;
using System.Threading.Tasks;

namespace QuartzExample
{
    [DisallowConcurrentExecution] // 禁止并发执行
    public class MailJobTest : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                Console.WriteLine("邮箱开始调度");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"定时器异常: {ex.Message}");
            }
        }
    }
}

启动调度

接下来,实例化并启动调度程序,并调度要执行的作业。

using Quartz;
using Quartz.Impl;
using System.Threading.Tasks;

namespace QuartzExample
{
    public class QuartzScheduler
    {
        private IScheduler _scheduler;

        public async Task StartScheduler()
        {
            // 创建调度器实例
            var factory = new StdSchedulerFactory();
            _scheduler = await factory.GetScheduler();
            await _scheduler.Start();

            // 创建任务
            var job = JobBuilder.Create<MailJobTest>()
                .WithIdentity("MailJob", "MailGroup")
                .Build();

            // 创建触发器
            var trigger = TriggerBuilder.Create()
                .WithIdentity("MailTrigger", "MailTriggerGroup")
                .WithCronSchedule("0/5 * * * * ?") // 每5秒执行一次
                .Build();

            // 调度任务
            await _scheduler.ScheduleJob(job, trigger);
        }

        public async Task StopScheduler()
        {
            if (_scheduler != null)
            {
                await _scheduler.Shutdown();
            }
        }
    }
}

调用示例

using System;
using System.Threading.Tasks;

namespace QuartzExample
{
    class Program
    {
        static async Task Main(string[] args)
        {
            var quartzScheduler = new QuartzScheduler();
            await quartzScheduler.StartScheduler();

            Console.WriteLine("按任意键停止调度...");
            Console.ReadKey();

            await quartzScheduler.StopScheduler();
        }
    }
}

取消任务调度

// 关闭
scheduler1.Shutdown().Wait();

耗时任务处理

对于耗时较长的任务,可以使用 [DisallowConcurrentExecution]​ 特性,确保任务在上一次执行完成后才会开始下一次执行。

[DisallowConcurrentExecution]
public class LongRunningJob : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        // 模拟耗时操作
        await Task.Delay(5000);
        Console.WriteLine("耗时任务完成");
    }
}

封装 ​ExQuartz 方法到类中

为了更好地组织代码并提高可维护性,我们可以将 ExQuartz​ 方法封装到一个类中。以下是封装后的 QuartzScheduler​ 类,同时考虑了 scheduler​ 的存储和访问。

QuartzScheduler 类

using Quartz;
using Quartz.Impl;
using System.Threading.Tasks;

namespace UploadLogiData.Quartzs
{
    /// <summary>
    /// 封装了 ExLogiQuartz 方法和对 scheduler 的访问
    /// </summary>
    public class QuartzScheduler
    {
        /// <summary>
        /// 调度器实例
        /// </summary>
        private IScheduler _scheduler;

        /// <summary>
        /// 静态定义主窗体(假设 Form1 是主窗体)
        /// </summary>
        public static Form1 Form { get; set; }

        /// <summary>
        /// 启动调度器并安排任务
        /// </summary>
        public async Task ExLogiQuartz()
        {
            Form.DisplayListboxMsg("检测任务启动!");

            // 创建调度器实例
            var factory = new StdSchedulerFactory();
            _scheduler = await factory.GetScheduler();
            await _scheduler.Start();

            // 创建第一个任务:LogiDownloadJob,每5秒执行一次
            var job1 = JobBuilder.Create<LogiDownloadJob>()
                .WithIdentity("LogiJob", "LogiGroup")
                .Build();
            var trigger1 = TriggerBuilder.Create()
                .WithIdentity("LogiTrigger", "LogiTriggerGroup")
                .WithCronSchedule("0/5 * * * * ?") // 每5秒执行一次
                .Build();
            await _scheduler.ScheduleJob(job1, trigger1);

            // 创建第二个任务:MailJobTest,每天下午3点10分执行一次
            var job2 = JobBuilder.Create<MailJobTest>()
                .WithIdentity("MailJob", "MailGroup")
                .Build();
            var trigger2 = TriggerBuilder.Create()
                .WithIdentity("MailTrigger", "MailTriggerGroup")
                .WithCronSchedule("0 10 15 * * ?") // 每天下午3点10分执行一次
                .Build();
            await _scheduler.ScheduleJob(job2, trigger2);
        }

        /// <summary>
        /// 获取调度器实例
        /// </summary>
        public IScheduler Scheduler => _scheduler;

        /// <summary>
        /// 关闭调度器
        /// </summary>
        public async Task ShutdownScheduler()
        {
            if (_scheduler != null)
            {
                await _scheduler.Shutdown();
            }
        }
    }
}

调用示例

以下是使用 QuartzScheduler​ 类的示例代码:

using System;
using System.Threading.Tasks;

namespace UploadLogiData
{
    class Program
    {
        public static async Task Main(string[] args)
        {
            // 初始化主窗体(假设 Form1 是主窗体)
            QuartzScheduler.Form = new Form1();

            // 创建 QuartzScheduler 实例
            var quartzScheduler = new QuartzScheduler();

            // 启动调度器并安排任务
            await quartzScheduler.ExLogiQuartz();

            Console.WriteLine("调度器已启动,按任意键关闭调度器...");
            Console.ReadKey();

            // 关闭调度器
            await quartzScheduler.ShutdownScheduler();
            Console.WriteLine("调度器已关闭。");
        }
    }
}

Cron 表达式

表达式格式

Quartz.NET 使用 Cron 表达式来定义复杂的调度规则。Cron 表达式由7个字段组成:秒、分、时、日、月、星期、年(可选)。

字段名 允许的值 允许的特殊字符
0-59 , - * /
0-59 , - * /
小时 0-23 , - * /
1-31 , - * ? / L W C
1-12 或 JAN-DEC , - * /
星期 1-7 或 SUN-SAT , - * ? / L C #
年(可选) 空或 1970-2099 , - * /

表达式例子

表达 含义
0 0 12 * * ? 每天中午12点(中午)触发
0 15 10 ? * * 每天上午10:15触发
0 15 10 * * ? 每天上午10:15触发
0 15 10 * * ? * 每天上午10:15触发
0 15 10 * * ? 2005 2005年期间,每天上午10:15触发
0 * 14 * * ? 每天从下午2点开始,直到下午2:59结束,每分钟触发一次
0 0/5 14 * * ? 每天从下午2点开始,直到下午2:55,每5分钟触发一次
0 0/5 14,18 * * ? 每天从下午2点开始到下午2:55结束,每5分钟触发一次,并且每天下午6点开始到下午6:55结束,每5分钟触发一次
0 0-5 14 * * ? 每天从下午2点开始,直到下午2:05结束,每分钟触发一次
0 10,44 14 ? 3 WED 3月的每个星期三下午2:10和2:44 pm触发。
0 15 10 ? * MON-FRI 每个星期一,星期二,星期三,星期四和星期五的上午10:15触发
0 15 10 15 * ? 每个月的15日上午10:15触发
0 15 10 L * ? 每个月的最后一天上午10:15触发
0 15 10 L-2 * ? 每个月的倒数第二个上午10:15触发
0 15 10 ? * 6L 每个月的最后一个星期五上午10:15触发
0 15 10 ? * 6L 每个月的最后一个星期五上午10:15触发
0 15 10 ? * 6L 2002-2005 在2002、2003、2004和2005年的每个月的最后一个星期五上午10:15触发
0 15 10 ? * 6#3 每个月的第三个星期五上午10:15触发
0 0 12 1/5 * ? 从每月的第一天开始,每月每5天在中午12点(中午)触发。
0 11 11 11 11 ? 每年11月11日上午11:11触发。
0 * * * * ? 每1分钟整点触发一次
0 0 * * * ? 每天每1小时整点触发一次
0 0 10 * * ? 每天10点触发一次
0 2 9 * * ? // 每天9点02分执行一次
0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟触发 
0 30 9 1 * ? 每月1号上午9点半
0 15 10 15 * ? 每月15日上午10:15触发
*/5 * * * * ? 每隔5秒执行一次
0 */1 * * * ? 每隔1分钟执行一次
0 0 5-15 * * ? 每天5-15点整点触发
0 0/3 * * * ? 每三分钟触发一次
0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟触发 
0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟触发
0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时
0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 
0 0 12 ? * WED 表示每个星期三中午12点
0 0 17 ? * TUES,THUR,SAT 每周二、四、六下午五点
0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44触发 
0 15 10 ? * MON-FRI 周一至周五的上午10:15触发
0 0 23 L * ? 每月最后一天23点执行一次
0 15 10 L * ? 每月最后一日的上午10:15触发 
0 15 10 ? * 6L 每月的最后一个星期五上午10:15触发 
0 15 10 * * ? 2005 2005年的每天上午10:15触发 
0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一个星期五上午10:15触发 
0 15 10 ? * 6#3 每月的第三个星期五上午10:15触发

标签:触发,Quartz,15,10,await,调度,scheduler,任务调度
From: https://www.cnblogs.com/ouyangkai/p/18683538/quartz-task-scheduling-zbfejj

相关文章

  • CyberRT-任务调度-scheduler
    调度空间主要关注三个方面通信和数据传输以及监控SchedulerConfTransportConfPerfConfOSProcess(操作系统进程)、OSThread(操作系统线程)、CyberRTTask(用户空间协程)。CyberRT调度器有两种调度策略,分别为Choreo与Classic,Choreo策略是CyberRT下......
  • 十天速成:打造你的AI低代码系统(7.分布式任务调度)
        前言1:系统架构及部署应用2:AI辅助开发和AI辅助测试(基于IDEA插件开发)    2.1IDEA插件开发方法3:无代码-动态列表4:无代码-拖拽表单5:无代码-任务流     5.1任务流-组件案例    5.2 第三方系统健康性检查案例    5.3 如何开......
  • 25、【OS】【Nuttx】最小系统初始化分析(3):任务调度(二)
    背景接上篇wiki24、【OS】【Nuttx】最小系统初始化分析(3):任务调度(一)继续分析Ready队列的更新合并Pending队列还是nxsched_merge_pending,上篇wiki分析到了当前head任务被lock时,无法更新Ready队列。现在继续,当任务没被lock时,此时会遍历Pending队列,并逐一将Pen......
  • SpringBoot 整合 Quartz 定时任务框架
    本文没有聊到 Java 其他的实现定时任务的方法啥的~,只是对使用Quartz做了一个小实践一、简单聊一聊QuartzQuartz是一个完全由Java编写的开源作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz其实就是通过一个调度线程不断的扫描数据库......
  • Coravel:一个可轻松实现任务调度、队列、邮件发送的开源项目
    推荐一个轻量级的任务调度开源项目。01项目简介Coravel是一个.NET开源任务调度库,只需简单代码、几乎零配置就可以实现多种功能柜,如任务调度、队列、缓存、事件广播和邮件发送等。该项目特点就是让这些通常复杂的功能变得易于访问和使用,同时提供简洁、直观的语法。02核心功能......
  • 基于甘特图的任务调度与跟踪工具
    在当今复杂的项目管理领域,工具的种类繁多且功能各异。常见的项目管理工具包括禅道、Trello、Jira、MicrosoftProject等。这些工具在不同层面上助力项目管理,从任务分配到进度跟踪,从团队协作到资源管理。甘特图作为一种直观且有效的任务调度与跟踪工具,在众多项目管理工具中脱颖而......
  • 解决Spring boot集成quartz时service注入失败为null的问题
    解决Springboot集成quartz时service注入失败为null的问题一、报错信息二、代码任务类源代码配置类原代码三、注入失败原因四、解决的思路11、任务类修改2、配置类修改五、解决的思路2一、报错信息java.lang.NullPointerException:nullatfarbun.server.schedul......
  • (十).NET6.0 搭建基于Quartz组件的定时调度任务
    1.添加Quartz定时器组件2.新建类库项目Wsk.Core.QuartzNet,并且引用包类库项目。然后新建一个中间调度类,叫QuartzMiddleJob3.新建一个Job工厂类,叫YsqJobFactory,用来获取刚刚创建的中间调度类的服务4.新建一个通用执行计划类,叫YsqJobSchedule,用于每次任务都通过该计划进行......
  • 找不到quartz.dll文件或quartz.dll文件丢失该怎么办?
    在大部分情况下出现我们运行或安装软件,游戏出现提示丢失某些DLL文件或OCX文件的原因可能是原始安装包文件不完整造成,原因可能是某些系统防护软件将重要的DLL文件识别为可疑,阻止并放入了隔离单里,还有一些常见的DLL文件缺少是因为系统没有安装齐全的微软运行库,还有部分情况是因为......
  • GPU加速主要通过并行化计算任务,适合大规模数据处理和计算密集型应用。 多线程并发适用
    GPU加速和多线程并发是提高计算密集型任务性能的两种重要技术。它们在不同领域(如深度学习、科学计算、图像处理等)得到了广泛应用。下面,我将详细介绍这两者的概念、原理、以及如何结合它们进行高效计算。1. GPU加速1.1 GPU加速的基本原理GPU(图形处理单元)最初设计用于图像和视......