翻譯|行業資訊|編輯:胡濤|2023-09-15 11:01:18.890|閱讀 122 次
概述:本文演示ASP.NET Core 中使用 Hangfire,歡迎查閱~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
本文演示如何使用 HangFire,這是一個流行的開源庫,用于 .NET Core 應用程序中的后臺處理。本文構建了一個簡單的應用程序,該應用程序執行一些后臺處理,以演示使用 PostgreSql 作為數據庫來存儲數據和 dotConnect for PostgreSQL 作為 PostgreSQL 的數據提供程序所涵蓋的概念。
為了從數據庫中存儲和檢索數據,我們將使用dotConnect for PostgreSQL,這是一個構建在 ADO.NET 之上的高性能增強型 PostgreSQL 數據提供程序,可以在連接和斷開連接模式下工作。
您將需要以下工具來處理代碼示例:
在本文中,我們將構建一個簡單的應用程序,該應用程序將演示如何在 ASP.NET 6 中自定義 HTTP 400 和 404 錯誤響應。以下是我們在本文中將遵循的步驟來完成此操作:
在當今的應用程序中,某些操作(例如發送電子郵件、創建報告或上傳大文件)可能需要很長時間才能完成。如果您的應用程序在請求-響應周期內同步執行這些操作,則可能會導致超時和延遲。這就是后臺任務可以提供幫助的地方。
后臺任務是在后臺執行操作的任務,這樣應用程序的工作流程就不會被中斷,最重要的是,當前正在執行的線程不會被阻塞。換句話說,后臺任務允許您將耗時或非關鍵操作與應用程序的主要邏輯分開。
后臺任務通常異步運行,用于從應用程序的實際請求響應周期中卸載耗時或資源密集型進程,從而允許它們在后臺運行。通過將后臺任務與即時用戶交互分離,后臺任務允許您發送電子郵件、修改數據或對警報進行排隊,而無需立即用戶響應。
您可以將后臺作業配置為定期觸發。這對于自動化正常流程(例如備份、同步和生成每日報告)非常有用。您可以專注于核心功能,并將某些后臺任務卸載到其他組件,從而提高代碼的可維護性。
Hangfire是一個開源庫,用于處理.NET和ASP.NET Core應用程序中的后臺任務。它提供了一種簡單有效的方法,用于在正常的請求-響應周期之外執行長時間、耗時或重復的任務。
通過提供統一且易于使用的API,Hangfire簡化了任務后臺處理的實現。它無需編寫復雜的線程代碼或手動管理后臺處理基礎設施。由于其直觀的 API 和豐富的功能,Hangfire 在管理 NET 應用程序中的輔助任務方面受到了開發人員的歡迎。
以下是 Hangfire 的主要特點:
Hangfire 使用三個主要組件來管理作業。其中包括存儲、客戶端和服務器。存儲組件負責存儲作業信息。客戶端組件用于創建后臺作業并根據配置的存儲提供程序將作業存儲在數據存儲中。服務器組件負責執行所有后臺作業。
在本部分中,我們將學習如何在 Visual Studio 2022 中創建新的 ASP.NET 6 Core Web API 項目。
現在,請按照下列步驟操作:
我們將在本文中使用該項目。
在此示例中,我們將研究如何在 ASP.NET Core 中使用 Hangfire 實現自動資源監視器。該應用程序以預定義的時間間隔在后臺創建并運行重復任務,然后檢索 CPU 和內存使用信息并將其存儲在 PostgreSQL 數據庫表中。
您可以使用 pgadmin 工具創建數據庫。要使用此啟動此工具創建數據庫,請按照以下步驟操作:
現在按照下面給出的步驟在剛剛創建的數據庫中創建一個表:
下面給出表格腳本供您參考:
CREATE TABLE perfdata ( id serial PRIMARY KEY, job_Id VARCHAR ( 255 ) NOT NULL, cpu_usage VARCHAR ( 255 ) NOT NULL, memory_usage VARCHAR ( 255 ) NOT NULL );
我們將在本文的后續部分中使用此表來演示如何使用 dotConnect for PostgreSQL 在 ASP.NET Core 中進行集成測試。
接下來,您應該將所需的 NuGet 包安裝到您的項目中。您可以從 Visual Studio 內的 NuGet 包管理器工具安裝它們,也可以使用以下命令從 NuGet 包管理器控制臺安裝它們:
PM> Install-Package Devart.Data.PostgreSql PM> Install-Package Hangfire PM> Install-Package Hangfire.MemoryStorage
dotConnect for PostgreSQL 是基于 ADO.NET 技術構建的 PostgreSQL 高性能數據提供程序,為構建基于 PostgreSQL 的數據庫應用程序提供了全面的解決方案。
將 Hangfire 安裝到您的項目中后,下一步就是對其進行配置。您可以使用以下代碼將 Hangfire 服務添加到服務集合中:
builder.Services.AddHangfire(c => c.UseMemoryStorage()); builder.Services.AddHangfireServer();
您可以在儀表板中查看與正在運行或已完成的作業相關的實時數據。您可以通過下面給出的代碼片段來開啟此功能:
app.UseHangfireDashboard();
在本節中,我們將研究如何在 Hangfire 中創建作業以在后臺執行處理,同時我們的應用程序繼續響應。
Hangfire 為以下作業類型提供支持:
您可以使用BackgroundJob.Enqueue 方法在Hangfire 中創建后臺作業。即發即忘作業是指僅被觸發或執行一次的作業。創建一個名為 CustomJobController 的新 API 控制器,并在其中寫入以下代碼:
[Route("api/[controller]")] [ApiController] public class CustomJobController : ControllerBase { private readonly ILogger _logger; private readonly IBackgroundJobClient _backgroundJobClient; public CustomJobController(ILogger<CustomJobController> logger, IBackgroundJobClient backgroundJobClient) { _logger = logger; _backgroundJobClient = backgroundJobClient; } [HttpGet] public IActionResult Get() { var jobId = _backgroundJobClient.Enqueue(() => FireAndForgetJob(null)); Thread.Sleep(5000); return Ok($"Job Id: {jobId} completed..."); } public Task FireAndForgetJob(PerformContext context) { var jobId = context.BackgroundJob.Id; _logger.LogInformation($"Executing Job Id: {jobId}..."); return Task.CompletedTask; } }
當您執行應用程序并點擊 CustomJobController 的 HttpGet 端點時,您可以看到即發即棄作業執行一次,如圖 1 所示:
以下代碼片段展示了如何在 Hangfire 中創建延遲作業:
var jobId = BackgroundJob.Schedule(() => Console.WriteLine("This is an example of a delayed job"), TimeSpan.FromDays(1));
在 Hangfire 中,連續作業是指父作業執行完成后立即運行的作業。您還可以在 Hangfire 中創建和管理延續任務或作業。以下代碼片段顯示了如何在 Hangfire 中創建延續任務:
var id = BackgroundJob.Enqueue(() => InitializeInputData()); BackgroundJob.ContinueWith(id, () => ValidateInputData());
重復性作業是根據計劃執行的作業。例如,您可以有一個每周每分鐘、每小時或每小時執行一次的重復作業。要在 Hangfire 中處理重復作業,您應該使用 IRecurringJobManager 接口。實際上,您應該在 CustomJobController 類的構造函數中注入 IRecurringJobManager 接口類型的實例,如下面給出的代碼清單所示:
[Route("api/[controller]")] [ApiController] public class CustomJobController : ControllerBase { private readonly ILogger _logger; private readonly IRecurringJobManager _recurringJobManager; public CustomJobController(ILogger<CustomJobController> logger, IRecurringJobManager recurringJobManager) { _logger = logger; _recurringJobManager = recurringJobManager; } [HttpGet] public IActionResult Get() { var jobId = Guid.NewGuid().ToString(); _recurringJobManager.AddOrUpdate(jobId, () => CustomRecurringJob(jobId), Cron.Minutely); Thread.Sleep(5000); return Ok($"Job Id: {jobId} completed..."); } public Task CustomRecurringJob(string jobId) { _logger.LogInformation($"Executing Job Id: {jobId} at {DateTime.Now}"); return Task.CompletedTask; } }
當您執行應用程序并訪問 HttpGet 端點時,您可以看到作業每分鐘執行一次,如圖 2 所示:
現在讓我們在 Hangfire 中創建一個重復作業并使用它來檢索 CPU 和內存使用數據。以下代碼應該如何獲取計算機上的資源使用信息:
private dynamic GetResourceUsageForProcess() { string currentProcessName = Process.GetCurrentProcess().ProcessName; PerformanceCounter cpuCounter = new PerformanceCounter("Process", "% Processor Time", currentProcessName, true); PerformanceCounter memoryCounter = new PerformanceCounter("Process", "Private Bytes", currentProcessName, true); cpuCounter.NextValue(); memoryCounter.NextValue(); Task.Delay(500); dynamic result = new ExpandoObject(); result.CPU = Math.Round(cpuCounter.NextValue() / Environment.ProcessorCount, 2); result.RAM = Math.Round(memoryCounter.NextValue() / 1024 / 1024, 2); return result; }
現在資源使用信息已可用,您應該將此信息存儲在數據庫中。
下面給出的 StoreResourceUsageData 方法顯示了如何在 PostgreSql 數據庫中保存 CPU 和內存使用數據。
public void StoreResourceUsageData(string job_id, string cpu_usage, string memory_usage) { try { using ( PgSqlConnection pgSqlConnection = new PgSqlConnection ("User Id = postgres; Password = sa123#;" + "host=localhost;database=demo; license key=Specify your license key here;")) { using (PgSqlCommand cmd = new PgSqlCommand()) { cmd.CommandText = "INSERT INTO perfdata (job_id, cpu_usage, memory_usage) " + "VALUES (:job_id, :cpu_usage, :memory_usage)"; Thread.Sleep(250); cmd.Connection = pgSqlConnection; cmd.Parameters.AddWithValue("job_id", job_id); cmd.Parameters.AddWithValue("cpu_usage", cpu_usage); cmd.Parameters.AddWithValue("memory_usage", memory_usage); if (pgSqlConnection.State != System.Data.ConnectionState.Open) pgSqlConnection.Open(); var state = pgSqlConnection.State; cmd.ExecuteNonQuery(); } } } catch (Exception ex) { throw; } }
下面給出CustomJobController的完整源碼,供參考:
[Route("api/[controller]")] [ApiController] public class CustomJobController: ControllerBase { private readonly ILogger _logger; private readonly IRecurringJobManager _recurringJobManager; protected static PerformanceCounter cpuCounter; protected static PerformanceCounter memoryCounter; public CustomJobController(ILogger < CustomJobController > logger, IRecurringJobManager recurringJobManager) { _logger = logger; _recurringJobManager = recurringJobManager; } [HttpGet] public IActionResult Get() { var jobId = Guid.NewGuid().ToString(); _recurringJobManager.AddOrUpdate(jobId, () => CustomRecurringJob(jobId), Cron.Minutely); Thread.Sleep(5000); return Ok($"Job Id: {jobId} completed..."); } public Task CustomRecurringJob(string job_id) { _logger.LogInformation($"Executing Job Id: {job_id} at {DateTime.Now}"); var resourceUsage = GetResourceUsageForProcess(); string cpu_usage = resourceUsage.CPU.ToString(); string memory_usage = resourceUsage.RAM.ToString(); StoreResourceUsageData(job_id, cpu_usage, memory_usage); return Task.CompletedTask; } private dynamic GetResourceUsageForProcess() { string currentProcessName = Process.GetCurrentProcess().ProcessName; PerformanceCounter cpuCounter = new PerformanceCounter ("Process", "% Processor Time", currentProcessName, true); PerformanceCounter memoryCounter = new PerformanceCounter ("Process", "Private Bytes", currentProcessName, true); cpuCounter.NextValue(); memoryCounter.NextValue(); Task.Delay(500); dynamic result = new ExpandoObject(); result.CPU = Math.Round(cpuCounter.NextValue() / Environment.ProcessorCount, 2); result.RAM = Math.Round(memoryCounter.NextValue() / 1024 / 1024, 2); return result; } public void StoreResourceUsageData(string job_id, string cpu_usage, string memory_usage) { try { using(PgSqlConnection pgSqlConnection = new PgSqlConnection ("User Id = postgres; Password = sa123#;" + "host=localhost;database=demo; license key=Your license key;")) { using(PgSqlCommand cmd = new PgSqlCommand()) { cmd.CommandText = "INSERT INTO perfdata “ + “(job_id, cpu_usage, memory_usage) " + "VALUES (:job_id, :cpu_usage, :memory_usage)"; Thread.Sleep(250); cmd.Connection = pgSqlConnection; cmd.Parameters.AddWithValue("job_id", job_id); cmd.Parameters.AddWithValue("cpu_usage", cpu_usage); cmd.Parameters.AddWithValue("memory_usage", memory_usage); if (pgSqlConnection.State != System.Data.ConnectionState.Open) pgSqlConnection.Open(); var state = pgSqlConnection.State; cmd.ExecuteNonQuery(); } } } catch (Exception ex) { throw; } } }
當您運行應用程序時,您可以看到我們之前創建的數據庫表中存儲的 CPU 和內存使用信息。
Hangfire 是一個優秀的庫,用于將作業集成到 .NET 和 .NET Core 應用程序中。您可以使用它在特定時間、定期或基于 cron 表達式來安排您的作業。通過使用 Hangfire,您可以提高應用程序的響應能力。借助 Hangfire 和 ASP.NET Core,您可以在后臺高效地完成耗時的任務,從而最大限度地提高應用程序的性能和用戶體驗。
數據庫管理工具交流群:765665608 歡迎進群交流討論
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn