随着 .NET 9 发布,后台任务调度和定时任务管理变得更简单、更高效。本文将展示如何在 .NET 9 中使用 Hangfire 构建定时任务系统,并讲解从开发到生产的最佳实践。
一、Hangfire 简介
Hangfire 是一个成熟的 .NET 后台任务框架,支持:
-
Fire-and-Forget:立即执行一次任务
-
Delayed:延迟执行
-
Recurring:周期性任务
-
Continuations:任务链
-
Dashboard 可视化:监控任务状态和失败
Hangfire 的核心优势:
-
无需额外服务:可以直接运行在 ASP.NET Core 中。
-
持久化支持:SQL Server、Redis、MongoDB 等。
-
稳定可靠:任务执行失败可自动重试。
-
易于扩展:支持 DI、日志、分布式任务等。
二、创建 .NET 9 项目并安装依赖
-
创建 .NET 9 Web API 项目:
dotnet new web -n HangfireNet9Demo
cd HangfireNet9Demo -
安装 Hangfire 和内存存储(测试用):
dotnet add package Hangfire
dotnet add package Hangfire.MemoryStorage -
如果是生产环境推荐使用 SQL Server:
dotnet add package Hangfire.SqlServer
三、配置 Hangfire
在 Program.cs 中进行配置。NET 9 支持 最小 API 风格:
using Hangfire;
using Hangfire.MemoryStorage;
using Hangfire.Common;
var builder = WebApplication.CreateBuilder(args);
// 配置 Hangfire 服务
builder.Services.AddHangfire(config =>
{
// 测试环境使用内存存储
config.UseMemoryStorage();
// 生产环境推荐:
// config.UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireDb"));
});
builder.Services.AddHangfireServer();
var app = builder.Build();
// 启用 Hangfire Dashboard,默认路径 /hangfire
app.UseHangfireDashboard();
// 根路由测试
app.MapGet("/", () => "Hangfire with .NET 9 is running...");
四、创建定时任务
1. Fire-and-Forget(立即执行任务)
app.Lifetime.ApplicationStarted.Register(() =>
{
BackgroundJob.Enqueue(() => Console.WriteLine("立即执行的任务"));
});
2. Delayed(延迟任务)
app.Lifetime.ApplicationStarted.Register(() =>
{
BackgroundJob.Schedule(() => Console.WriteLine("延迟 1 分钟执行"), TimeSpan.FromMinutes(1));
});
3. Recurring(周期任务)
周期任务通常用于定时报告、邮件或数据清理:
app.Lifetime.ApplicationStarted.Register(() =>
{
var recurringJobManager = app.Services.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate(
"say-hello-job",
Job.FromExpression(() => Console.WriteLine("Hello Hangfire .NET 9!")),
"*/1 * * * *", // 每分钟执行
new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }
);
});
💡 注意:
-
Cron 表达式必须是字符串。
-
Job.FromExpression让 Hangfire 能够序列化方法调用。 -
RecurringJobOptions可设置时区、队列等。
五、任务监控与管理
Hangfire 自带 Dashboard,可以监控:
-
执行历史
-
失败任务
-
任务重试
-
队列状态
访问:
http://localhost:5000/hangfire
在生产环境中,可以设置 身份验证:
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization = new[] { new MyAuthorizationFilter() }
});
六、生产环境注意事项
-
持久化存储:MemoryStorage 仅适合测试,生产请使用 SQL Server 或 Redis。
-
任务重试 :Hangfire 默认重试 10 次,可通过
[AutomaticRetry(Attempts = 5)]调整。 -
队列隔离:复杂任务可设置不同队列,防止长任务阻塞短任务。
-
分布式任务:多服务器部署可共享同一数据库,自动协调任务执行。
-
日志与监控:结合 ILogger 或第三方监控系统,记录任务执行详情。
七、完整 Program.cs 示例 (.NET 9)
using Hangfire;
using Hangfire.MemoryStorage;
using Hangfire.Common;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHangfire(config => config.UseMemoryStorage());
builder.Services.AddHangfireServer();
var app = builder.Build();
app.UseHangfireDashboard();
app.MapGet("/", () => "Hangfire with .NET 9 is running...");
// Fire-and-Forget
app.Lifetime.ApplicationStarted.Register(() =>
{
BackgroundJob.Enqueue(() => Console.WriteLine("立即执行的任务"));
BackgroundJob.Schedule(() => Console.WriteLine("延迟 1 分钟执行"), TimeSpan.FromMinutes(1));
var recurringJobManager = app.Services.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate(
"say-hello-job",
Job.FromExpression(() => Console.WriteLine("Hello Hangfire .NET 9!")),
"*/1 * * * *",
new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }
);
});
app.Run();
✅ 总结
-
Hangfire + .NET 9 提供了一个轻量、可视化、可靠的定时任务解决方案。
-
内存存储适合开发调试,生产环境应使用持久化存储。
-
Cron 表达式、Job 表达式、队列与重试机制是核心概念。
-
Dashboard 让你实时监控任务执行状态