×

.NET 开源项目任务调度组件汇总

独孤求败 独孤求败 发表于2026-05-03 14:49:44 浏览34 评论0

抢沙发发表评论

在日常开发中,我们经常遇到需要“延迟执行”“定时执行”或“后台处理”的需求,比如:订单支付成功后30分钟自动取消、每天凌晨同步数据、发送批量邮件等。如果只用简单的Timer,往往会遇到持久化、重试、管理界面等棘手问题。幸好,.NET生态中有一批成熟的开源框架,能帮你轻松搞定这些场景。本文就带你全面了解Hangfire、Quartz.NET、FluentScheduler、Coravel、ScheduleMaster以及内置的Timer类,并告诉你什么时候该用哪个。


Hangfire —— 持久化、自带监控面板的后台作业神器

Hangfire是我个人最推荐的方案之一,尤其适合ASP.NET Core应用。它最大的亮点是:自带Web监控面板,作业失败后可以自动重试,并且默认把任务存进数据库(SQL Server、Redis等),应用重启也不会丢任务。

核心功能:

  • 队列任务:将方法调用丢进后台队列,立刻返回响应,不阻塞用户请求。
    BackgroundJob.Enqueue(() => Console.WriteLine("Hello!"));

  • 延迟任务:推迟一段时间再执行。
    BackgroundJob.Schedule(() => Console.WriteLine("5分钟后执行"), TimeSpan.FromMinutes(5));

  • 定时任务(CRON):使用内置的Cron.Daily或自定义CRON表达式。
    RecurringJob.AddOrUpdate(() => Console.Write("每日运行"), Cron.Daily);

  • 持久化存储:默认支持SQL Server和Redis。SQL Server开箱即用,适合大多数业务;Redis性能极高,适合高吞吐场景。

  • 自动重试:任务抛异常时会自动重试(默认10次),你也可以用[AutomaticRetry(Attempts = 3)]特性控制。

  • 实例方法调用:不仅支持静态方法,还能结合IoC容器调用实例方法,比如从容器中解析EmailService并调用其Send方法。

  • Web监控面板:只需一行中间件配置,就能在/hangfire地址看到所有作业的执行情况、失败记录,还能手动触发。

  • 多队列与并发控制:可以为不同重要性的任务分配不同队列,并控制工作线程数。

使用前提:需要配置持久化(如SQL Server)并添加app.UseHangfireDashboard()。对于中小型项目,Hangfire几乎是后台作业的首选。

官网:https://www.hangfire.io/


Quartz.NET —— 功能最全面的老牌任务调度框架

Quartz.NET是Java版Quartz在.NET上的移植,历史悠久、功能极其强大。它的核心理念是 Job(任务) 和 Trigger(触发器) 分离,一个任务可以绑定多个触发器,一个触发器也可以触发多个任务。如果你需要非常复杂的调度逻辑(比如每月最后一个周五的上午10:15执行),Quartz.NET是最好的选择。

Quartz比.NET内置Timer强在哪?

  • 支持持久化:任务和触发器可以保存在数据库里,应用重启后恢复。
  • 调度灵活:不仅支持固定间隔,还支持日历式的复杂时间点(如每周一至周五、排除节假日)。
  • 线程池管理:默认使用线程池执行作业,不会因为任务过多而耗尽线程。
  • 提供管理API:可以动态添加、删除、暂停、恢复任务,无需重启应用。

简单示例

// 创建一个任务
IJobDetail job = JobBuilder.Create<MyJob>()
    .WithIdentity("job1""group1")
    .Build();

// 创建一个触发器,每10秒执行一次
ITrigger trigger = TriggerBuilder.Create()
    .WithIdentity("trigger1""group1")
    .StartNow()
    .WithSimpleSchedule(x => x.WithIntervalInSeconds(10).RepeatForever())
    .Build();

// 调度器执行
scheduler.ScheduleJob(job, trigger);

适用场景:复杂的企业级调度、需要大量动态管理任务、对可靠性要求极高的系统。不过它的学习曲线比较陡,配置也稍显繁琐。

官网:https://www.quartz-scheduler.net/
GitHub:https://github.com/quartznet/quartznet


FluentScheduler —— 轻量级、流畅API的调度库

如果你觉得Quartz.NET太重,又不需要Hangfire那么强的持久化和监控,那么FluentScheduler正合适。它只做一件事:用流畅的语法优雅地配置定时任务。

特点

  • 极简配置:继承Registry类,在构造函数中用Schedule方法配置任务。
  • 支持多种调度模式:按月、按周、按天、按特定时间、按间隔。
  • 轻量无依赖:非常适合小型项目、控制台程序或Windows服务。

示例

public class MyRegistry : Registry
{
    public MyRegistry()
    {
        Schedule<MyJob>().ToRunNow().AndEvery(2).Seconds();
        Schedule<MyOtherJob>().ToRunEvery(1).Days().At(80);
    }
}

适用场景:不需要任务持久化、不需要管理界面,只要简单的“每隔X分钟执行一次”或“每天凌晨运行”的小项目。FluentScheduler已经停止更新有几年了,但功能稳定,仍然可用。

官网:https://fluentscheduler.github.io/
GitHub:https://github.com/fluentscheduler/FluentScheduler


Coravel —— 一站式“小而美”的工具箱

Coravel是一个年轻但非常有潜力的框架,它的口号是“零配置的任务调度、缓存、队列、邮件、事件广播”。如果你希望用一个库同时解决多种基础设施问题,Coravel很值得尝试。

调度部分用法

  1. ConfigureServices中注册调度服务和自定义任务(需要实现IInvocable接口):
services.AddScheduler();
services.AddTransient<UpdateTrendJob>();
  1. Configure管道中配置调度规则:
var provider = app.ApplicationServices;
provider.UseScheduler(scheduler =>
{
    scheduler.Schedule<UpdateTrendJob>()
        .EveryThirtyMinutes()
        .Weekday();
});
  1. 自定义任务类实现IInvoke(或IInvocable)接口的Invoke方法:
public class UpdateTrendJob : IInvocable
{
    private readonly IZmRobotHelper _helper;
    public UpdateTrendJob(IZmRobotHelper helper) => _helper = helper;
    public async Task Invoke() => await _helper.UpdateRankingJob();
}

优点:学习成本极低,语法非常优雅,而且自带缓存、队列等实用功能。缺点是目前社区规模和文档不如Hangfire丰富。

文档:https://docs.coravel.net/


ScheduleMaster —— 国产开源的分布式任务调度系统

ScheduleMaster是一个基于.NET Core 3.1构建的分布式任务调度系统,它本身不是一个库,而是一个完整的调度中心(类似XXL-JOB)。它有独立的Web管理界面,支持多节点部署、任务依赖、告警等企业级特性。

技术栈:ASP.NET Core 3.1 + EF Core + MySQL + Quartz.NET + jQuery。

适用场景:需要集中管理大量定时任务、跨多个服务实例、需要UI配置和监控的中大型系统。如果你不想自己从头搭建调度平台,ScheduleMaster是一个很好的选择。

Gitee:https://gitee.com/hey-hoho/ScheduleMasterCore


Timer 类 —— 最基础的定时器,简单场景足够用

最后提一下.NET内置的System.Timers.Timer。它是最轻量的解决方案,适合非常简单的周期性任务,比如每隔10秒检查一次某个状态。

基本用法

var timer = new System.Timers.Timer(5000); // 间隔5秒
timer.Elapsed += (sender, e) => 
{
    Console.WriteLine("执行任务");
};
timer.AutoReset = true// 重复执行
timer.Start();

缺点也很明显:没有持久化(应用重启任务就丢了)、不能设置复杂的CRON时间、无法自动重试、没有管理界面。所以它只适合辅助性的、允许丢失的简单后台逻辑。

文档:https://docs.microsoft.com/en-us/dotnet/api/system.timers.timer


总结与选型建议

为了方便你决策,我把这几个方案按场景做了个快速对比:

方案
持久化
管理界面
复杂度
典型场景
Hangfire
✅ 支持
✅ 内置
绝大多数Web应用的后台作业
Quartz.NET
✅ 支持
需额外集成
复杂的企业级调度、动态管理任务
FluentScheduler
轻量简单的小项目
Coravel
❌(调度本身不持久)
想要“一把梭”解决多个基础问题
ScheduleMaster
✅ 支持
✅ 完善
中(需单独部署)
分布式任务调度中心
Timer
最低
辅助性的、允许丢失的简单逻辑

个人建议

  • 如果你的项目是ASP.NET Core,首选Hangfire。一句话配置就能拥有可靠的持久化和可视化监控,真心好用。
  • 如果调度逻辑极其复杂(比如日历排除、任意时间表达式),选Quartz.NET
  • 如果只是控制台小工具,不想引入外部数据库,FluentSchedulerCoravel都非常优雅。
  • 如果你们公司已经有一套微服务体系,需要一个独立的调度中心,可以试试ScheduleMaster
  • 内置Timer只建议在本机辅助功能中使用,生产环境慎用。

每个框架都有自己的闪光点,没有绝对的“最好”,只有最合适当下业务场景的选择。希望这篇文章能帮你理清思路,写出更健壮的定时任务代码。


群贤毕至

访客