https://procodeguide.com/programming/hangfire-in-aspnet-core-schedule-jobs/
如何使用ASP.NET Core 中的 Hangfire 實現作業調度
本文詳細介紹了如何在ASP.NET Core應用程序中集成 Hangfire,這是一種在 .NET Core 和基於 .NET 的應用程序中調度后台作業的一種比較簡單的方法。后台作業或任務允許程序員在不同的線程上執行代碼,但調度和監控后台作業是一項難以實現的任務。Hangfire 簡化了在 ASP.NET Core 中處理后台作業的任務。
目錄
為什么或何時在 .NET Core 中安排后台作業?
Hangfire簡介
Hangfire 的后台 Job 類型
即發即忘
延遲執行
任務延續執行
Hangfire Pro 的其他工作類型
批處理作業
延續在 ASP.NET Core 中實現
Hangfire 即在 .NET Core 中安排后台作業
創建一個新的 ASP.NET Core WebAPI 項目
安裝所需的 Hangfire NuGet 包
在啟動時配置 Hangfire
添加 Hangfire 儀表板I
Hangfire 數據庫在 ASP.NET Core 中使用
Hangfire 創建作業
即發即忘的工作
延遲工作
經常性工作
繼續工作
讓我們運行代碼並檢查結果
概括
下載源代碼
為什么或何時在 .NET Core 中安排后台作業?
可能有一些 Web 請求需要花費大量時間來執行,例如生成成功插入的報告或發送電子郵件/短信作為交易完成的確認。這些請求可能需要未知的時間才能完成,並且讓用戶在這段時間內查看等待指示器並不能很好地處理請求。
想法是盡快為需要很長時間才能完成的請求解鎖用戶屏幕,以便用戶能夠執行其他任務。盡管用戶在長時間運行的活動完成之前已被解鎖,但這些活動的完成也很重要,因為它們是請求業務邏輯的一部分。
這是后台作業進入畫面的地方,就像在后台運行其余活動一樣,就像在不同的線程上一樣,以便主線程已被釋放以供用戶執行其他活動。
Hangfire簡介
我們在我們的應用程序中看到了后台作業的使用,但如果我們必須為后台作業創建和監控構建一個框架,那么這將是一項復雜的任務,可能需要付出很多努力。此外,這是一個設計特性,而不是一個功能特性,所以在這上面花費太多時間不會讓所有利益相關者都滿意。這是可以使用 Hangfire 的地方。
Hangfire是一個簡單易用的開源庫,它可以輕松地在 .NET Core 和 .NET 應用程序中實現后台作業。ASP.NET Core 中的 Hangfire 允許創建后台作業,甚至提供監控功能。
ASP.NET Core 中的 Hangfire 甚至支持持久存儲,如 Microsoft SQL Server、Redis(作為Hangfire Pro 的一部分)等,用於存儲作業信息,防止應用程序在池重新啟動時丟失作業信息。存儲作業信息可確保作業按照定義的類型執行,並且如果在作業執行期間發生任何異常,也會重試作業。
Hangfire 支持所有主要的日志框架,並將完整的作業執行信息記錄到為應用程序配置的日志記錄目的地。
Hangfire 通過確保作業根據其調度標准至少執行一次來提供后台作業的可靠性
ASP.NET Core 應用程序中的 Hangfire 可以是簡單的或分布式的,即創建作業的服務器/應用程序可以與執行作業的服務器/應用程序分開。這是可能的,因為作業信息存儲在可以在不同服務器/應用程序之間共享的數據庫中。
Hangfire 的后台 Job 類型
使用 ASP.NET Core 中的 Hangfire,您可以創建以下類型的后台作業
即發即忘(Fire and Forget )
顧名思義,Fir and Forget 作業只執行一次,並且在創建后立即執行。這些主要用於釋放主線程,使用戶體驗更加靈敏。
延遲
顧名思義,這些作業是在一些延遲后執行的。此延遲,即等待時間是可配置的,並在創建時排隊。執行類似於用后即停。這可用於可以在峰值負載窗口之外運行的作業。
多次執行
這些是計划作業,通常在每個定義的時間間隔內執行多次。可以配置這些作業的頻率,從幾毫秒到幾年不等。這些可以是每天或每周生成數據轉儲或報告的作業。
延續
Continuation 允許您定義一個工作流,即您可以配置多個(父延續作業)后台作業,這些后台作業可以根據父作業的完成情況鏈接在一起。即第二個作業應該執行,前提是第一個/父作業已正確執行。
Hangfire Pro 的其他工作類型
批處理作業
可以將多個后台作業鏈接在一起以形成批處理作業,以便它們同時一起執行。
批量延續
當父批次的作業完成時,即啟動批處理中的所有作業,然后繼續后台作業將啟動,鏈接繼續作業將啟動。
在 ASP.NET Core 中實現 Hangfire 即在 .NET Core 中安排后台作業
創建一個新的 ASP.NET Core WebAPI 項目
為了在 ASP.NET Core 中實現 Hangfire,讓我們創建一個新的 ASP.NET Core Web API 項目,在其中實現 Hangfire。
我將使用 Visual Studio 2019 社區版和 .NET Core 5 創建一個新的 Web API 項目
- 啟動 Visual Studio 2019
- 在初始屏幕上選擇創建一個新項目,如下所示
- 接下來從顯示的項目類型模板列表中選擇 ASP.NET Core Web Application 並單擊 Next 按鈕,如下面的屏幕截圖所示
- 然后輸入項目\解決方案的名稱ProCodeGuide.Samples.Hangfire,提供項目將保存在本地磁盤上的路徑並單擊創建按鈕,如下所示
)
\5. 最后選擇 .NET Core Framework 為 ASP.NET Core 5.0,應用程序類型為 ASP.NET Core Web API,啟用 OpenAPI Support 以進行測試並點擊 Create 按鈕,如下所示
)
這將創建項目並在 Visual Studio 2019 中加載相同的項目,如下圖所示
安裝所需的 Hangfire NuGet 包
您將需要安裝 NuGet 包 Hangfire,如下所示,以將 Hangfire 引用包含到您的應用程序中。
ASP.NET Core 中的 Hangfire 包依賴於其他三個與 Hangfire NuGet 包一起安裝的引用,如下所示
在啟動時配置 Hangfire
既然已經安裝了 Hangfire 所需的所有 NuGet 包,我們將不會在 Startup.cs 文件中配置 Hangfire。
我們將在類 Startup 的 ConfigureServices 方法中的 IServiceCollection 上添加對擴展方法 AddHangfire 和 AddHangfireServer 的調用。
public void ConfigureServices(IServiceCollection 服務)
{
services.AddHangfire(x => x.UseSqlServerStorage("Server=(localdb)\\mssqllocaldb;Database=ProCodeGuide.Samples.Hangfire;Trusted_Connection=True;MultipleActiveResultSets=true"));
services.AddHangfireServer();
//為便於閱讀,已刪除剩余代碼
}
AddHangfire – 這會將 ASP.NET Core 中的 Hangfire 添加到依賴項注入容器中,並采用 Action 委托,我們使用它設置了 SQL Server 數據庫的連接字符串,以使用 SQL Server 數據庫作為 Hangfire 實現的存儲。
作為一個演示應用程序,我在啟動類中硬編碼了 SQL Server 連接字符串,但這不是一個好習慣,所以請在 appsettings.json 文件中配置您的 SQL Server 連接字符串並從那里設置它,以便您擁有特定於環境的 SQL Server連接字符串
AddHangfireServer - 這將 Hangfire Server 添加到依賴注入容器,用於配置和運行作業。
添加 Hangfire 儀表板 UI
現在讓我們將 Hangfire 的中間件添加到添加 Hangfire 儀表板 UI 所需的ASP.NET Core 中間件管道。我們將在 IApplicationBuilder 實例上添加對擴展方法 UseHangfireDashboard 的調用。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ProCodeGuide.Samples.Hangfire v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseHangfireDashboard();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
檢查 Hangfire 儀表板 UI
現在我們已經在 ASP.NET Core 應用程序中集成了 Hangfire,讓我們運行應用程序並檢查 Hangfire 的儀表板。
從 Visual Studio 構建和運行應用程序后,您應該會看到以下 swagger 屏幕。
現在導航到 URL /Hangfire 后,您應該能夠在 ASP.NET Core 中看到 Hangfire 的儀表板,如下所示。
從儀表板 UI,您將能夠查看計划作業並監控作業狀態。儀表板甚至允許您手動運行儀表板中可見的作業。儀表板上的可用信息如下
作業- 存儲在數據庫中的所有作業都將在此處以不同的狀態顯示,如已安排、已排隊、正在處理、已成功、已失敗、已刪除和等待中。
重試- 由於先前執行期間的某些失敗而重試的作業列表。
循環作業- 可以看到所有已安排為循環作業的作業列表。
服務器- 可以看到所有添加到依賴注入容器的 Hangfire 服務器。這些服務器負責處理作業。
請注意,由於儀表板 UI 會公開特定於應用程序的敏感數據,甚至允許手動執行作業,因此確保僅授權用戶可以訪問此儀表板非常重要。
Hangfire 在 ASP.NET Core 中默認提供的唯一安全性是它只允許對 Dashboard UI 的本地請求
Hangfire 數據庫
我們確實在 ASP.NET Core 中為 Hangfire 配置了 SQL Server 數據庫,作為啟動時 Hangfire 配置的一部分 (AddHangfire)。當 hangfire 啟動時,它會在數據庫中查找所需的架構,如果該架構不存在,那么它將創建如下所示的相同
Hangfire 數據庫用於存儲作業信息。
在 ASP.NET Core 中使用 Hangfire 創建作業
為了在 ASP.NET Core 中演示 Hangfire 中的不同類型的作業,首先讓我們創建一個虛擬服務,即 DummyEmailService,它實現了接口 IEmailService,它通過向控制台窗口寫入郵件已發送而不是發送實際郵件來模擬郵件發送。
現在,如果您想實現一個使用 MailKit 庫和 SMTP 服務器發送電子郵件的工作電子郵件服務,那么您可以閱讀我關於如何在 ASP.NET Core 中發送電子郵件的另一篇文章
添加具有函數 SendEmail 的接口 Services/IEmailService.cs,它將在虛擬服務 DummyEmailService 中實現,以寫入已發送電子郵件的控制台。
public interface IEmailService
{
void SendEmail(string backGroundJobType, string startTime);
}
添加將實現接口 IEmailService 的類 Services/DummyEmailService 並將包含 SendEmail 方法的實現以寫入控制台窗口。
public DummyEmailService : IDummyEmailService
{
public void SendEmail(string backGroundJobType, string startTime)
{
Console.WriteLine(backGroundJobType + " - " + startTime + " - Email Sent - " + DateTime.Now.ToLongTimeString());
}
}
現在在應用程序依賴注入容器中注冊此服務,以便將其注入控制器。要將 DummyEmailService 添加到容器中,請在 Startup.cs 文件的方法 ConfigureServices 中添加以下代碼行
services.AddTransient<IEmailService, DummyEmailService>();
現在讓我們添加一個新的 API 控制器,即 EmailController,我們將注入 IEmailService 以從控制器操作方法 SendEmail 中的服務調用方法 SendEmail。
[Route("[controller]")]
[ApiController]
public class EmailController : ControllerBase
{
private IEmailService _emailService = null;
public EmailController(IEmailService emailService)
{
_emailService = emailService;
}
[HttpGet]
public string SendMail()
{
_emailService.SendEmail("Direct Call", DateTime.Now.ToLongTimeString());
return "Email Initiated";
}
}
現在運行應用程序,當您導航到 URL /Email 時,您應該在屏幕下方
下面我們來看看如何在 ASP.NET Core 中實現 Hangfire 中的每一種作業
即發即忘的工作
Hangfire.BackgroundJob.Enqueue 用於創建 Fire-and-Forget 后台任務。這些作業在創建后幾乎立即執行,並且只執行一次。
BackgroundJob.Enqueue(() => _emailService.SendEmail("Fire-and-Forget Job", DateTime.Now.ToLongTimeString()));
延遲工作
Hangfire.BackgroundJob.Schedule 用於創建 Delayed 后台任務。這些作業是延遲創建的,並在配置的延遲時間過后執行。
BackgroundJob.Schedule(() => _emailService.SendEmail("Delayed Job",DateTime.Now.ToLongTimeString()),TimeSpan.FromSeconds(30));
經常性工作
Hangfire.RecurringJob.AddOrUpdate 用於創建循環后台任務。這些可以是按照定義的頻率執行的每分鍾、每天或每周的工作。
RecurringJob.AddOrUpdate(() => _emailService.SendEmail("Recurring Job", DateTime.Now.ToLongTimeString()),Cron.Minutely);
繼續工作
Hangfire.BackgroundJob.ContinueJobWith 用於創建延續后台任務。這些作業會在鏈接的先前作業成功執行后立即執行。
var jobId = BackgroundJob.Schedule(() => _emailService.SendEmail("Continuation Job 1", DateTime.Now.ToLongTimeString()), TimeSpan.FromSeconds(45));BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation Job 2 - Email Reminder - " + DateTime.Now.ToLongTimeString()));
最后,我修改了 EmailController 中 SendMail 操作方法中的代碼,如下所示,以演示 ASP.NET Core 中 Hangfire 中可用的每種類型的后台作業的執行模式
[HttpGet]public string SendMail(){ _emailService.SendEmail("Direct Call", DateTime.Now.ToLongTimeString()); BackgroundJob.Enqueue(() => _emailService.SendEmail("Fire-and-Forget Job", DateTime.Now.ToLongTimeString())); BackgroundJob.Schedule(() => _emailService.SendEmail("Delayed Job", DateTime.Now.ToLongTimeString()),TimeSpan.FromSeconds(30)); RecurringJob.AddOrUpdate(() => _emailService.SendEmail("Recurring Job", DateTime.Now.ToLongTimeString()),Cron.Minutely); var jobId = BackgroundJob.Schedule(() => _emailService.SendEmail("Continuation Job 1", DateTime.Now.ToLongTimeString()), TimeSpan.FromSeconds(45)); BackgroundJob.ContinueJobWith(jobId, () => Console.WriteLine("Continuation Job 2 - Email Reminder - " + DateTime.Now.ToLongTimeString())); return "Email Initiated";}
讓我們運行代碼並檢查結果
現在讓我們運行代碼來檢查 ASP.NET Core 中 Hangfire 中可用的不同類型作業的執行模式。
運行應用程序后導航到 URL /Email 這應該調用 SendEmail 以獲取 EmailController 中的操作方法,並且應該顯示以下屏幕。但是在后台,所有配置的作業類型都應該根據它們的執行模式創建和觸發。
讓我們查看控制台窗口中的 ASP.NET Core 中 Hangfire 中不同類型的作業是否已被觸發
我們可以從上面的屏幕中看到,所有作業都是按照它們的執行模式觸發的。
概括
在本文中,我們將了解后台作業、ASP.NET Core 中的 Hangfire 以及 ASP.NET Core 中 Hangfire 中可用的不同類型作業的實現。
我們還看到,甚至還有一個付費版本的 Hangfire,即Hangfire Pro,它支持 Redis 作為數據庫,還支持一些額外的復雜作業類型,如批處理和批處理延續。
我希望你喜歡這篇文章,在下面的評論部分讓我知道你的反饋
下載源代碼
在 ASP.NET Core 中實現 Hangfire 的源代碼下載鏈接https://github.com/procodeguide/ProCodeGuide.Samples.Hangfire