Quartz.NET是Quartz的.NET移植版本,是一个功能齐全的开源作业调度系统,可用于从最小的应用程序到大型企业系统。它提供了强大的调度功能,支持简单的间隔调度、Cron表达式调度等多种方式,同时支持任务持久化、集群部署等高级特性。
Quartz.NET核心概念
在使用Quartz.NET之前,需要先了解它的几个核心组件:
- IJob:任务接口,所有需要执行的定时任务都需要实现这个接口,在Execute方法中编写具体的任务逻辑。
- JobDetail:任务的详细信息,用于定义任务的实例,包含任务的类型、名称、组名以及任务相关的参数。
- Trigger:触发器,用于定义任务执行的时间规则,分为简单触发器SimpleTrigger和Cron触发器CronTrigger两类。
- Scheduler:调度器,是Quartz.NET的核心组件,负责管理所有的JobDetail和Trigger,按照触发器的规则触发任务执行。
项目准备与依赖安装
首先创建一个新的C#控制台项目,然后通过NuGet安装Quartz.NET包。可以在NuGet包管理器中搜索Quartz,安装最新稳定版本,也可以通过包管理控制台执行以下命令安装:
// 安装Quartz.NET的NuGet命令 Install-Package Quartz
简单定时任务实现
1. 创建任务类
首先创建一个实现IJob接口的任务类,编写具体的任务执行逻辑:
using Quartz;
using System;
using System.Threading.Tasks;
namespace QuartzDemo
{
// 实现IJob接口的任务类
public class SimpleJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
// 任务执行的具体逻辑,这里打印当前时间和任务提示
Console.WriteLine($"简单定时任务执行,当前时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
await Task.CompletedTask;
}
}
}
2. 配置调度器与触发器
接下来在程序入口处配置调度器、任务详情和触发器,启动调度:
using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
namespace QuartzDemo
{
class Program
{
static async Task Main(string[] args)
{
// 1. 创建调度器工厂
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
// 2. 获取调度器实例
IScheduler scheduler = await schedulerFactory.GetScheduler();
// 3. 启动调度器
await scheduler.Start();
// 4. 创建任务详情,指定任务类型为SimpleJob
IJobDetail jobDetail = JobBuilder.Create<SimpleJob>()
.WithIdentity("simpleJob", "jobGroup1") // 设置任务名称和组名
.Build();
// 5. 创建简单触发器,设置任务每3秒执行一次,无限重复
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("simpleTrigger", "triggerGroup1") // 设置触发器名称和组名
.StartNow() // 立即开始
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(3) // 间隔3秒
.RepeatForever()) // 无限重复
.Build();
// 6. 将任务详情和触发器注册到调度器
await scheduler.ScheduleJob(jobDetail, trigger);
// 保持程序运行,方便观察任务执行效果
Console.WriteLine("定时任务已启动,按任意键退出...");
Console.ReadKey();
// 7. 关闭调度器
await scheduler.Shutdown();
}
}
}
运行程序后,可以看到每3秒控制台会输出一次任务执行的信息,说明简单定时任务已经生效。
带参数的任务实现
有时候任务执行需要传递一些参数,Quartz.NET支持通过JobDataMap传递参数,以下是实现方式:
1. 修改任务类接收参数
using Quartz;
using System;
using System.Threading.Tasks;
namespace QuartzDemo
{
public class ParamJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
// 从JobDataMap中获取传递的参数
JobDataMap dataMap = context.JobDetail.JobDataMap;
string userName = dataMap.GetString("userName");
int executeCount = dataMap.GetInt("executeCount");
Console.WriteLine($"带参数任务执行,用户:{userName},执行次数:{executeCount},时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
await Task.CompletedTask;
}
}
}
2. 配置时传递参数
// 创建带参数的任务详情
IJobDetail paramJobDetail = JobBuilder.Create<ParamJob>()
.WithIdentity("paramJob", "jobGroup1")
.UsingJobData("userName", "测试用户") // 传递字符串参数
.UsingJobData("executeCount", 1) // 传递数值参数
.Build();
// 创建触发器,每5秒执行一次
ITrigger paramTrigger = TriggerBuilder.Create()
.WithIdentity("paramTrigger", "triggerGroup1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(5)
.RepeatForever())
.Build();
// 注册任务
await scheduler.ScheduleJob(paramJobDetail, paramTrigger);
使用Cron表达式实现复杂调度
如果需要实现更复杂的调度规则,比如每天凌晨2点执行、每周一上午10点执行等,可以使用CronTrigger配合Cron表达式实现。Cron表达式由7个字段组成,分别是秒、分、时、日、月、周、年(年可选)。
常见的Cron表达式示例:
| Cron表达式 | 含义 |
|---|---|
| 0 0 2 * * ? | 每天凌晨2点执行 |
| 0 0 10 ? * MON | 每周一上午10点执行 |
| 0 */5 * * * ? | 每5分钟执行一次 |
| 0 0 9-18 * * MON-FRI | 工作日每天9点到18点每小时执行一次 |
以下是使用Cron表达式的示例代码:
using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
namespace QuartzDemo
{
class CronDemo
{
static async Task RunCronJob()
{
ISchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();
IJobDetail cronJob = JobBuilder.Create<SimpleJob>()
.WithIdentity("cronJob", "jobGroup2")
.Build();
// 创建Cron触发器,设置每天凌晨2点执行
ITrigger cronTrigger = TriggerBuilder.Create()
.WithIdentity("cronTrigger", "triggerGroup2")
.WithCronSchedule("0 0 2 * * ?") // Cron表达式
.Build();
await scheduler.ScheduleJob(cronJob, cronTrigger);
Console.WriteLine("Cron定时任务已启动");
}
}
}
注意事项
- 默认情况下Quartz.NET的任务实例是每次执行时新创建的,如果需要单例任务,可以配置JobBuilder的
StoreDurably或者使用其他的实例管理方式。 - 如果任务执行时间超过触发间隔,需要根据业务需求配置 misfire 策略,避免出现任务漏执行或者重复执行的问题。
- 生产环境中如果需要任务持久化或者集群部署,需要配置Quartz.NET使用数据库存储调度信息,默认是内存存储,程序重启后调度信息会丢失。
Quartz.NET的功能远不止本文介绍的这些内容,还包括监听器、插件、事务支持等高级特性,开发者可以根据实际需求查看官方文档进行扩展使用。
C#Quartz_NET定时调度任务调度修改时间:2026-06-15 19:15:52