前情提要
筆者在上篇已介紹Coravel
短小精幹的排程利器,固定週期排程部份皆使用Coravel
套件完成,然而使用者需求越來越清楚的狀況下,意識到無法滿足所以使用者需求,事情是這樣的,使用者的某些作業需要從畫面操作,並將該項作業排進排程中,且是一次性作業,例如:使用者透過介面去設定日結作業的需求,我們會由介面呼叫API,於API中設定好某個時間點去執行該「日結作業」服務。
以上述的需求,在Coravel套件是無法做到的,Coravel是有Queue的機制,不過無法設定特定時間,筆者最近是時不時看Asp.Net Core RoadMap上所列之相關技術及推薦套件,對於上面推薦的套件,都會想要來試看看,畢竟大神們整理過的,肯定有其厲害之處,剛好於Task Scheduling作業中有推薦三套相關套件,筆者已經使用過Coravel,試試看其他,廢話不多說,趕緊來介紹今天的主角HangFire
吧。
筆者開發環境及語言版本使用如下:
- Visual Studio 2019
- .net core 3.1
- Web API專案
內容
建立WebAPI專案
筆者這邊省略這個步驟,提供以下語法,也可以使用Visual Studio來建立專案
1 2 3 4
| mkdir HangFireDemo dotnet new webapi -n HangFireDemo.API dotnet new sln -n HangFireDemo dotnet sln HangFireDemo.lsn add .\HangFireDemo.Api\HangFireDemo.API.csproj
|
初始化及引用
使用HangFire服務,要加三個nuget套件,分別為
- Hangfire.Core
- Hangfire.AspNetCore
- Hangfire.SqlServer
以上套件中,Hangfire.Core
、Hangfire.AspNetCore
為必要套件,接著依照自己的Persistent
需求,可以選擇安裝SqlServer、Redis、PostgreSQL、MongoDb及其他,筆者這邊選擇SqlServer
這個選項,因此會需要多安裝一個Hangfire.SqlServer
安裝完成後於Startup
做初始化的動作,筆者這邊直接使用官網的AspNetCore Applications
範例程式,有包含DashBoard
功能。因要使用Sql Server
當作persistent媒介,因此需先建立一個空的DB,必且於appsettings
中設定連線字串。
基本上不需要事先建立相關資料表,HangFire
在第一次啟動時會自動建立,但必須要知道公司的資料庫政策,筆者在公司環境時,必須要事先建好資料庫,因為application無法有create table
的權限,只有read/write
權限,因此提醒讀者要考量一下實際執行環境
1 2 3 4
| "ConnectionStrings": { "HangfireConnection": "Server=.;Initial Catalog=HangfireTest;Database=HangfireTest;Trusted_Connection=True;" }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| services.AddHangfire(configuration => configuration .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions { CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), QueuePollInterval = TimeSpan.Zero, UseRecommendedIsolationLevel = true, UsePageLocksOnDequeue = true, DisableGlobalLocks = true }));
services.AddHangfireServer();
|
1 2
| app.UseHangfireDashboard();
|
Hangfire任務介紹及實作
Hangfire的任務,可以分成以下三種類型:
- 一次性的任務
- 延遲性任務,設定特定時間執行
- 週期性任務
筆者針對這三種類型使用一個Controller
來示範,為了示範可以使用注入的服務,宣告一個IJobService
及其方法Execute
,再者宣告一個JobService
(實作IJobService
),實作Execute
方法部份,筆者這邊以簡單的引入NLog
套件並將執行過程紀錄於檔案中。
Hangfire任務實作
1 2 3 4 5
| public interface IJobService { void OneTimeExecute(); void DelayExecute(); void SchedulerExecute(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class JobService : IJobService { private static readonly Logger _logger = LogManager.GetCurrentClassLogger(); public void OneTimeExecute() { _logger.Info("One Time Job Execute!"); }
public void DelayExecute() { _logger.Info("Delay Job Execute!"); }
public void SchedulerExecute() { _logger.Info("Scheduler Job Execute!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| using Hangfire;
[ApiController] [Route("[controller]")] public class HomeController : ControllerBase {
private readonly IJobService _jobService; public HomeController(IJobService jobService) { _jobService = jobService; }
[HttpGet("onetime")] public IActionResult OneTime() { BackgroundJob.Enqueue<IJobService>(x => x.OneTimeExecute()); return Ok(); }
[HttpGet("delay")] public IActionResult DelayJob() { BackgroundJob.Schedule<IJobService>(x => x.DelayExecute(), TimeSpan.FromSeconds(30)); return Ok(); }
[HttpGet("scheduler")] public IActionResult Scheduler() { RecurringJob.AddOrUpdate<IJobService>(x => x.SchedulerExecute(), Cron.Minutely); return Ok(); } }
|
結論
跟著筆者實作,會感覺得Hangfire
的厲害,提供的三種排程執行方式,已足夠應付各式各樣的需求,以這篇的範例,應該可以構建各式各樣的排程任務。
參考: