在執行需要花費較久時間的工作時,如果不希望使用者等待,通常會告訴使用者這項任務正在進行中,等到執行完畢會透過 email 之類的方法通知使用者
這個時候我們就會需要用到 background job 來讓這個任務在 background threads 上執行
在 abp 中,建立 background job 的方法為繼承 BackgroundJob<TArgs>
或AsyncBackgroundJob<TArgs>
類別,或是可以直接實作 IBackgroundJob<TArgs>
介面
下面實作一個最簡單的同步 background job,模擬要寄送 email 的情況
public class SendEmailJob : BackgroundJob<User>, ITransientDependency { public override void Execute(User user) { Console.WriteLine($"Welcome user {user.Name} join to this platform"); } }
與一個非同步的 background job
public class SendEmailJobAsync : AsyncBackgroundJob<User>, ITransientDependency { public override async Task ExecuteAsync(User user) { Console.WriteLine($"Welcome user {user.Name} join to this platform"); } }
一個 background job 會定義一個 Execute
或是 ExecuteAsync
的方法,並且可以傳入參數,
background job 必須在 DI 中註冊,最簡單的辦法是實作 ITransientDependency
介面
在定義完 job 後,我們可以透過 inject IBackgroundJobManager
來新增 job 到 queue 中
public class UserAppService { private readonly IBackgroundJobManager _backgroundJobManager; public UserAppService(IBackgroundJobManager backgroundJobManager) { _backgroundJobManager = backgroundJobManager; } public override async Task<UserDto> CreateAsync(CreateUserDto input) { var user = ObjectMapper.Map<User>(input); // ... 略 _backgroundJobManager.Enqueue<SendEmailJob, User>(user); } }
我們傳入 user 給這個 job,backgroundJobManager 就會自動執行這個 job 並使用 user 當作參數來寄出 email
1. 在 UI 新增一個 user
2. 就可以在 console 看到執行 job 所印出的訊息
IBackgroundJobManager
實作的是 BackgroundJobManager 這個 class
1. 安裝 hangfire
Install-Package Abp.HangFire.AspNetCore Install-Package Hangfire.SqlServer // 這個就看你的 hangfire 要用什麼 storage
2. 在 startup 中註冊 handfire
services.AddHangfire(config => { config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default")); });
3. 在 configure 方法中加入 UseHangfireServer
app.UseHangfireServer();
4. 最後,將 abp 預設的 background job manager 替換成 hangfire,這邊就根據你是用什麼專案模板,我是用前後端分離的,所以要替換的檔案就在 [ProjectName].Web.Core 專案中的 [ProjectName]WebCoreModule.cs 這隻檔案中
[DependsOn( ...略 + typeof(AbpHangfireAspNetCoreModule) )] public class BackgroundJobWebCoreModule : AbpModule { ...略 public override void PreInitialize() { // hang fire + Configuration.BackgroundJobs.UseHangfire(); ... 略 } }
1. 在 UI 新增一個 user
2. 到 hangfire dashboard 中可以看到 job 被執行完畢
3. console 中也有印出值