Hangfire可用作任務調度,類似延遲任務、隊列任務、批量任務和定時任務等。
一、nuget Hangfire包
找到Hangfire.AspNetCore和Hangfire.SqlServer包,可以在nuget面板中找到或直接像如下方式安裝:
Install Package Hangfire.AspNetCore
Install Package Hangfire.SqlServer
二、在Startup.cs文件中加入以下代碼:
寫一個Hangfire的擴展類,如下所示:
public static class HangFireModule { public static IApplicationBuilder UseHangfire(this IApplicationBuilder app) { app.UseHangfireServer(); app.UseHangfireDashboard(); return app; } public static IServiceCollection AddHangfire(this IServiceCollection services) { services.AddHangfire(x => x.UseSqlServerStorage(ConfigurationSetting.Configuration["ConnectionString:MyDb_Hangfire"])); return services; } }
在Startup的ConfigureServices方法中,加入services.AddHangfire();
在Startup的Configure方法中,加入app.UseHangfire();
三、自動加入任務
1.在當前模塊中,新創建一個名為IHangfireTask的接口,將其注冊為瞬時生命周期服務。我們將要實現的是,從此以后,繼承該接口的類型都會被自動加入到任務調度中。
/// <summary> /// Hangfire任務接口,任何繼承該接口的都會加入到Hangfire任務 /// </summary> public interface IHangfireTask : ITransient { /// <summary> /// 運行hangfire任務 /// </summary> void Run(); }
ITransient接口的作用就是,將所有繼承ITransient的接口和類型注冊為瞬時生命周期的服務。
2.在HangFireModule中新增一個UseHangfireTask擴展方法,目的是在Startup的Configure方法中使用,在程序啟動的時候就執行該方法。
//運行Hangfire任務 public static void UseHangfireTask(this IApplicationBuilder app) { //找到繼承了IHangfireTask接口的實例 IList<IHangfireTask> list = ServiceLocator.Services.GetServices<IHangfireTask>()?.ToList(); if (list?.Count > 0) { foreach (var item in list) { item.Run(); } } }
加入到Startup的Configure方法中:
public void Configure(IApplicationBuilder app, IHostingEnvironment env,IServiceProvider serviceProvider) { ServiceLocator.SetServices(serviceProvider); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler(); } app.UseMvc(); app.UseSwagger(); app.UseSwaggerUi(); app.UseHangfire(); app.UseHangfireTask(); }
如此這樣,我們就做到了在程序剛啟動時,程序就會自動去找到繼承自IHangfireTask接口的所有類型並運行它們的Run()方法。
我們可以在Run()方法中實現諸如Hangfire的BackgroundJob或RecurringJob等任務。
接下來我們就用代碼來實現一下!
我們現在想實現一個定時任務,則看如下代碼:
public class RecurringTask:IHangfireTask { private log4net.ILog log => LogHelper.Log4NetInstance.LogFactory(typeof(RecurringTask)); public void RunTask() { log.Info("每分鍾執行一次定時任務"); } public void Run() { RecurringJob.AddOrUpdate(()=> RunTask(), "* * * * *"); } }
這里有一個地方需要注意,在使用RecurringJob或BackgroundJob的時候,就例如()=> RunTask()這個,RunTask方法的訪問修飾符必須是public。如果有必要,盡量在RunTask方法內被調用的其他方法的訪問修飾符也定義為public。
在Hangfire中,Cron表達式包含五個字段:分鍾、小時、日期、月份、周,因此定時任務最低也只能是一分鍾,沒有秒數可供選擇。
接下來我們看看程序運行的結果:
四、Hangfire的基本任務
1. BackgroundJob.Enqueue
作用:將一個任務放入到某個持久化的隊列中並挨個執行,以便程序可以繼續執行其他代碼。該任務只執行一次。
實現:BackgroundJob.Enqueue(() => RunTask());
2. BackgroundJob.Schedule
作用:將一個任務延遲到某個時間點后執行。
實現:BackgroundJob.Schedule(() => RunTask(), TimeSpan.FromSeconds(30));
即在30秒后才執行RunTask()方法。
3. RecurringJob.AddOrUpdate
作用:重復執行一個任務,一般用作定時任務處理。
實現:RecurringJob.AddOrUpdate(()=> RunTask(), "* * * * *");
即每分鍾都執行一次RunTask()方法。
4. BackgroundJob.ContinueWith
作用:類似工作流的形式,將多個任務連接起來按照順序執行。
實現:
string jobId = BackgroundJob.Schedule(() => Console.WriteLine("第一個任務"),TimeSpan.FromSeconds(10));
BackgroundJob.ContinueWith(jobId, () => RunTask());
注意:以上RunTask()方法的訪問修飾符必須是public。