NET 5使用HangFire定時任務


注意:
1. 當Hangfire服務由Web程序來啟用時,默認情況下,web應用程序中的Hangfire服務器實例在第一個用戶訪問您的站點之前不會啟動。甚至,有一些事件會在一段時間后導致web應用程序關閉(比如空閑超時應用程序池回收事件)。在這些情況下, “循環任務”和“延遲作業”將不會進入隊列,而“進入隊列的作業”將不會被處理。因此我們需要讓ASP.NET應用程序始終運行。(詳見官方的方法:Making ASP.NET application always running)

2. Hangfire Dashboard是一個你可以找到所有關於你的后台工作的信息的地方。它是作為一個OWIN中間件編寫的(如果你不熟悉OWIN,也不用擔心),所以你可以將它插入到你的 ASP.NET, ASP.NET MVC, Nancy, ServiceStack應用程序中,以及使用OWIN Self-Host 功能,在控制台應用程序或在Windows服務中托管Hangfire Dashboard服務。(詳見官方說明: Using Dashboard)

前言:
  定時任務調度問題,是一個老生常談的問題。網上有許多定時任務調度的解決方案,對於我而言很早以前主要是使用Window計划和Window服務來做任務定時執行,然后就開始使用定時任務調度框架Quartz.Net。但是卻一直沒有上手過Hangfire這個自帶后台任務調度面板,可以在后台手動執行任務的神奇的任務調度框架。前段時間終於開始對他下手了,通過在網上查閱了一些資料和查看了Hangfire在Github中的demo,終於在我自己的項目中用上了Hangfire。在該篇文章中主要簡單介紹一下什么是Hangfire,Hangfire的基本特征與優點和分別使用MySQL,MS SQL Server作為存儲使用。

一、Hangfire是什么:

  hangfire官網https://www.hangfire.io/

  Hangfire是一個開源的.NET任務調度框架,提供了內置集成化的控制台,可以直觀明了的查看作業調度情況,並且Hangfire不需要依賴於單獨的應用程序執行(如:windows服務,window計划)。並且支持持久性存儲。

二、Hangfire使用條件:

Hangfire與特定的.NET應用程序類型無關。您可以在ASP.NET Web應用程序,非ASP.NET Web應用程序,控制台應用程序或Windows服務中使用它。以下是要求:

1.NET Framework 4.5

2.永久存儲(Hangfire將后台作業和其他與處理有關的信息保留在永久性存儲器中,所以需要存儲庫來存儲如:MS SQL Server,Redis,MySQL,PostgreSql等)

3.Newtonsoft.Json庫≥5.0.1

三、Hangfire安裝和使用:

第一步:創建WebApi項目承載任務調度

在ASP.NET 應用程序下使用Hangfire安裝:

Install-Package Hangfire (SQlServer內置)

使用mysql作為存儲時我們需要安裝的NuGet:

Install-Package Hangfire.MySql.Core

修改appsettings.json配置文件,添加持久化作業數據的數據庫連接

<connectionStrings>
  <add name="sqlserver_connection" connectionString="Data Source=.;Initial Catalog=MyFirstDb;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>

第二步、創建作業業務類

/// <summary>
    ///  疫情業務類
    /// </summary>
    public class DiseaseService : IDiseaseService
    {
        private IHttpClientFactory _httpClientFactory = null;
       // private DiseaseDataContext _diseaseDataContext = null;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="httpClientFactory"></param>
        /// <param name="diseaseDataContext"></param>
        public DiseaseService(IHttpClientFactory httpClientFactory) //, DiseaseDataContext diseaseDataContext)
        {
            this._httpClientFactory = httpClientFactory;
            //_diseaseDataContext = diseaseDataContext;
        }
        /// <summary>
        /// 同步疫情
        /// </summary>
        /// <returns></returns> 
        public async Task<string> SyncDiseaseData()
        {
       //TODO同步疫情數據       return "";
        }

第三步、在startup.cs中注入Hangfire

ConfigureServices方法中添加

services.AddHttpClient();  //注入HttpClient
            #region hangfire
            var storage = new MySqlStorage(Configuration.GetConnectionString("DiseaseJobConnection")
                  , new MySqlStorageOptions { PrepareSchemaIfNecessary = true, TablePrefix = "Disease" });
            //GlobalConfiguration.Configuration.UseStorage(new MySqlStorage(storage, new MySqlStorageOptions
            //{
            //    TransactionIsolationLevel = IsolationLevel.ReadCommitted, // 事務隔離級別。默認值為讀提交。
            //    QueuePollInterval = TimeSpan.FromSeconds(15),             // 作業隊列輪詢間隔。默認值為15秒
            //    JobExpirationCheckInterval = TimeSpan.FromHours(1),       // 作業過期檢查間隔(管理過期記錄)。默認為1小時
            //    CountersAggregateInterval = TimeSpan.FromMinutes(5),      // 間隔到聚合計數器。默認為5分鍾
            //    PrepareSchemaIfNecessary = true,                          // 如果設置為true,則創建數據庫表。默認值為true
            //    DashboardJobListLimit = 50000,                            // 儀表板作業列表上限。默認值為50000 
            //    TransactionTimeout = TimeSpan.FromMinutes(1),             // 事務超時。默認為1分鍾
            //}));   
            services.AddHangfire(p => p.UseStorage(storage));
            #endregion 
            services.AddScoped<DiseaseService>(); //注入業務

在Configure方法中

//hangfire
            app.UseHangfireServer();
            app.UseHangfireDashboard();
            //作業
            RecurringJob.AddOrUpdate<DiseaseService>("SyncDiseaseInformation", p => p.SyncDiseaseData(), "0 9,12,18,0 * * ?");

運行程序后切換到hangfire管理頁面如下圖

 

 MS SQL Server的表

 

 常用命令

//支持基於隊列的任務處理:任務執行不是同步的,而是放到一個持久化隊列中,以便馬上把請求控制權返回給調用者。
var jobId = BackgroundJob.Enqueue(()=>WriteLog("隊列任務執行了!"));
 
//延遲任務執行:不是馬上調用方法,而是設定一個未來時間點再來執行,延遲作業僅執行一次
var jobId = BackgroundJob.Schedule(()=>WriteLog("一天后的延遲任務執行了!"),TimeSpan .FromDays(1));//一天后執行該任務
 
//循環任務執行:一行代碼添加重復執行的任務,其內置了常見的時間循環模式,也可基於CRON表達式來設定復雜的模式。【用的比較的多】
RecurringJob.AddOrUpdate(()=>WriteLog("每分鍾執行任務!"), Cron.Minutely); //注意最小單位是分鍾
 
//延續性任務執行:類似於.NET中的Task,可以在第一個任務執行完之后緊接着再次執行另外的任務
BackgroundJob.ContinueWith(jobId,()=>WriteLog("連續任務!"));

配置權限

app.UseHangfireServer();
            app.UseHangfireDashboard("/hangfire", new DashboardOptions
            {
                Authorization = new[] { new HangfireAuthorizationFilter() },
                IgnoreAntiforgeryToken = true,
                AppPath = "/swagger/index.html",
                DashboardTitle = "Abc Sys Hangfire Dashboard"
            });
            app.AddOrUpdateJobs();
/// <summary>
    /// HangfireAuthorizationFilter
    /// </summary>
    public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
    {
        /// <summary>
        /// no authorize
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public bool Authorize(DashboardContext context)
        {
            return true;
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM