使用 Hangfire 在 .NET 9 中實(shí)現(xiàn)可靠定時(shí)任務(wù)的最佳實(shí)踐
隨著 .NET 9 發(fā)布,后臺(tái)任務(wù)調(diào)度和定時(shí)任務(wù)管理變得更簡(jiǎn)單、更高效。本文將展示如何在 .NET 9 中使用 Hangfire 構(gòu)建定時(shí)任務(wù)系統(tǒng),并講解從開發(fā)到生產(chǎn)的最佳實(shí)踐。
一、Hangfire 簡(jiǎn)介
Hangfire 是一個(gè)成熟的 .NET 后臺(tái)任務(wù)框架,支持:
- Fire-and-Forget:立即執(zhí)行一次任務(wù)
- Delayed:延遲執(zhí)行
- Recurring:周期性任務(wù)
- Continuations:任務(wù)鏈
- Dashboard 可視化:監(jiān)控任務(wù)狀態(tài)和失敗
Hangfire 的核心優(yōu)勢(shì):
- 無需額外服務(wù):可以直接運(yùn)行在 ASP.NET Core 中。
- 持久化支持:SQL Server、Redis、MongoDB 等。
- 穩(wěn)定可靠:任務(wù)執(zhí)行失敗可自動(dòng)重試。
- 易于擴(kuò)展:支持 DI、日志、分布式任務(wù)等。
二、創(chuàng)建 .NET 9 項(xiàng)目并安裝依賴
創(chuàng)建 .NET 9 Web API 項(xiàng)目:
dotnet new web -n HangfireNet9Demo cd HangfireNet9Demo
安裝 Hangfire 和內(nèi)存存儲(chǔ)(測(cè)試用):
dotnet add package Hangfire dotnet add package Hangfire.MemoryStorage
如果是生產(chǎn)環(huán)境推薦使用 SQL Server:
dotnet add package Hangfire.SqlServer
三、配置 Hangfire
在 Program.cs 中進(jìn)行配置。NET 9 支持 最小 API 風(fēng)格:
using Hangfire;
using Hangfire.MemoryStorage;
using Hangfire.Common;
var builder = WebApplication.CreateBuilder(args);
// 配置 Hangfire 服務(wù)
builder.Services.AddHangfire(config =>
{
// 測(cè)試環(huán)境使用內(nèi)存存儲(chǔ)
config.UseMemoryStorage();
// 生產(chǎn)環(huán)境推薦:
// config.UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireDb"));
});
builder.Services.AddHangfireServer();
var app = builder.Build();
// 啟用 Hangfire Dashboard,默認(rèn)路徑 /hangfire
app.UseHangfireDashboard();
// 根路由測(cè)試
app.MapGet("/", () => "Hangfire with .NET 9 is running...");四、創(chuàng)建定時(shí)任務(wù)
1. Fire-and-Forget(立即執(zhí)行任務(wù))
app.Lifetime.ApplicationStarted.Register(() =>
{
BackgroundJob.Enqueue(() => Console.WriteLine("立即執(zhí)行的任務(wù)"));
});2. Delayed(延遲任務(wù))
app.Lifetime.ApplicationStarted.Register(() =>
{
BackgroundJob.Schedule(() => Console.WriteLine("延遲 1 分鐘執(zhí)行"), TimeSpan.FromMinutes(1));
});
3. Recurring(周期任務(wù))
周期任務(wù)通常用于定時(shí)報(bào)告、郵件或數(shù)據(jù)清理:
app.Lifetime.ApplicationStarted.Register(() =>
{
var recurringJobManager = app.Services.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate(
"say-hello-job",
Job.FromExpression(() => Console.WriteLine("Hello Hangfire .NET 9!")),
"*/1 * * * *", // 每分鐘執(zhí)行
new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }
);
});?? 注意:
- Cron 表達(dá)式必須是字符串。
Job.FromExpression讓 Hangfire 能夠序列化方法調(diào)用。RecurringJobOptions可設(shè)置時(shí)區(qū)、隊(duì)列等。
五、任務(wù)監(jiān)控與管理
Hangfire 自帶 Dashboard,可以監(jiān)控:
- 執(zhí)行歷史
- 失敗任務(wù)
- 任務(wù)重試
- 隊(duì)列狀態(tài)
訪問:
http://localhost:5000/hangfire
在生產(chǎn)環(huán)境中,可以設(shè)置 身份驗(yàn)證:
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization = new[] { new MyAuthorizationFilter() }
});
六、生產(chǎn)環(huán)境注意事項(xiàng)
- 持久化存儲(chǔ):MemoryStorage 僅適合測(cè)試,生產(chǎn)請(qǐng)使用 SQL Server 或 Redis。
- 任務(wù)重試:Hangfire 默認(rèn)重試 10 次,可通過
[AutomaticRetry(Attempts = 5)]調(diào)整。 - 隊(duì)列隔離:復(fù)雜任務(wù)可設(shè)置不同隊(duì)列,防止長任務(wù)阻塞短任務(wù)。
- 分布式任務(wù):多服務(wù)器部署可共享同一數(shù)據(jù)庫,自動(dòng)協(xié)調(diào)任務(wù)執(zhí)行。
- 日志與監(jiān)控:結(jié)合 ILogger 或第三方監(jiān)控系統(tǒng),記錄任務(wù)執(zhí)行詳情。
七、完整 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("立即執(zhí)行的任務(wù)"));
BackgroundJob.Schedule(() => Console.WriteLine("延遲 1 分鐘執(zhí)行"), 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();? 總結(jié)
- Hangfire + .NET 9 提供了一個(gè)輕量、可視化、可靠的定時(shí)任務(wù)解決方案。
- 內(nèi)存存儲(chǔ)適合開發(fā)調(diào)試,生產(chǎn)環(huán)境應(yīng)使用持久化存儲(chǔ)。
- Cron 表達(dá)式、Job 表達(dá)式、隊(duì)列與重試機(jī)制是核心概念。
- Dashboard 讓你實(shí)時(shí)監(jiān)控任務(wù)執(zhí)行狀態(tài)
到此這篇關(guān)于使用 Hangfire 在 .NET 9 中實(shí)現(xiàn)可靠定時(shí)任務(wù)的最佳實(shí)踐的文章就介紹到這了,更多相關(guān).net hangfire定時(shí)任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用AjaxPro.Net框架實(shí)現(xiàn)在客戶端調(diào)用服務(wù)端的方法
AjaxPro.Net是一個(gè)優(yōu)秀的.net環(huán)境下的Ajax框架,用法很簡(jiǎn)單,可以查閱相關(guān)資料,本文檔是一個(gè)簡(jiǎn)單的實(shí)例講述使用AjaxPro的幾個(gè)關(guān)鍵點(diǎn)。2011-02-02
Asp.net Core 3.1基于AspectCore實(shí)現(xiàn)AOP實(shí)現(xiàn)事務(wù)、緩存攔截器功能
這篇文章主要介紹了Asp.net Core 3.1基于AspectCore實(shí)現(xiàn)AOP實(shí)現(xiàn)事務(wù)、緩存攔截器功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Asp.Net程序目錄下文件夾或文件操作導(dǎo)致Session失效的解決方案
這篇文章主要介紹了Asp.Net程序目錄下文件夾或文件操作導(dǎo)致Session失效的解決方案,需要的朋友可以參考下2017-06-06
MVC項(xiàng)目結(jié)構(gòu)搭建及單個(gè)類的實(shí)現(xiàn)學(xué)習(xí)筆記1
這篇文章主要介紹了MVC項(xiàng)目結(jié)構(gòu)搭建及單個(gè)類在各個(gè)層次中的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
asp.net 模擬提交有文件上傳的表單(通過http模擬上傳文件)
通過HTTP模擬GET或POST請(qǐng)求,提交數(shù)據(jù)到服務(wù)端獲取響應(yīng),比較常見些;但如上傳文件到服務(wù)端,使用html form當(dāng)然簡(jiǎn)單了,而因環(huán)境所限有時(shí)需要使用模擬方法去提交有附件(文件上傳)的表單。2010-02-02
.NET單元測(cè)試使用AutoFixture按需填充的幾種方式和最佳實(shí)踐記錄
AutoFixture是一個(gè).NET庫,旨在簡(jiǎn)化單元測(cè)試中的數(shù)據(jù)設(shè)置過程,通過自動(dòng)生成測(cè)試數(shù)據(jù),它幫助開發(fā)者減少測(cè)試代碼的編寫量,使得單元測(cè)試更加簡(jiǎn)潔、易讀和易維護(hù),本文介紹.NET單元測(cè)試使用AutoFixture按需填充的幾種方式和最佳實(shí)踐記錄,感興趣的朋友一起看看吧2024-07-07
ASP.NET使用SignalR2實(shí)現(xiàn)服務(wù)器廣播
這篇文章介紹了ASP.NET使用SignalR2實(shí)現(xiàn)服務(wù)器廣播的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05
ASP.NET Core中自定義路由約束的實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET Core中自定義路由約束的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03

