項目慢慢就要開工了,不少園友都在問這個事情,看來大夥對這事很上心啊,事情須要一步步的來,儘可能寫出一個咱們都滿意的項目。之前每次在博客前面都會扯淡一下,不過不少人都抱怨這樣作很差,加上我這人扯淡起來就停不住,有時候還會很感性的說出一些話,因此之後寫博文儘可能少扯淡。(若是博文有不足之處,還望多多指正,我也會及時的修改,若是隻是單純的刷存在感,說一些過激的話,那我就不怎麼高興了)html
項目中不少時候都會使用到定時任務這樣一個功能需求,在.NET中對於完成定時任務的技術仍是不怎麼多的,.NET Framework具備「內置」定時器功能,經過System.Timers.Timer類。在使用Timer類須要面對的問題:計時器沒有持久化機制;計時器具備不靈活的計劃(僅能設置開始時間和重複間隔,沒有基於日期,時間等);計時器不使用線程池(每一個定時器一個線程);計時器沒有真正的管理方案 - 你必須編寫本身的機制,以便可以記住,組織和檢索任務的名稱等。若是須要在.NET實現定時器的功能,能夠嘗試使用如下這款開源免費的組件Quartz.Net組件。redis
上面介紹了兩種方式,在這裏就介紹另一種組件,那就是Hangfire組件。sql
在.NET和.NET Core應用程序中執行後臺處理的簡單方法。無需Windows服務或單獨的進程。由持久存儲支持,存儲方式有sqlserver、redis,mongodb等等。Hangfire支持全部類型的後臺任務 - 短期運行和長時間運行,CPU密集型和I / O密集型,一次性和週期性。mongodb
1.組件特色:express
2.組件功能:api
上面是對Hangfire組件背景的一些簡單介紹,下面咱們具體來了解一下Hangfire組件的使用方法。服務器
既然想要學習瞭解一個組件,固然須要知道是怎麼樣取使用,若是不能使用,學着也沒有什麼很大的用處,下面介紹一下Hangfire組件的一些經常使用方法。併發
1.ASP.NET MVC設置方式:app
public void Configuration(IAppBuilder app) { GlobalConfiguration.Configuration.UseSqlServerStorage("<connection string or its name>"); app.UseHangfireDashboard(); app.UseHangfireServer(); }
GlobalConfiguration
類是配置Hangfire的首選方式。這是一些方法的入口點,包括來自第三方存儲實現或其餘擴展的方法。用法很簡單,只需Hangfire
在應用程序初始化類中包含命名空間,並發現GlobalConfiguration.Configuration
屬性的擴展方法ide
2.控制檯設置方式:
GlobalConfiguration.Configuration .UseColouredConsoleLogProvider()
.UseSqlServerStorage(@"Server=.\sqlexpress;Database=Hangfire.Sample;Trusted_Connection=True;") .UseMsmqQueues(@".\Private$\hangfire{0}", "default", "critical");
3.基於隊列的任務處理:
var jobId = BackgroundJob.Enqueue( () => Console.WriteLine("Fire-and-forget!"));
4.延遲任務執行:
var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
5.循環任務執行:
RecurringJob.AddOrUpdate( () => Console.WriteLine("Recurring!"), Cron.Daily);
6.繼續在其父做業完成時執行:
BackgroundJob.ContinueWith( jobId, () => Console.WriteLine("Continuation!"));
7.批處理方法:
var batchId = BatchJob.StartNew(x => { x.Enqueue(() => Console.WriteLine("Job 1")); x.Enqueue(() => Console.WriteLine("Job 2")); });
8.當父批次中的全部後臺做業完成時,批處理繼續:
BatchJob.ContinueWith(batchId, x => { x.Enqueue(() => Console.WriteLine("Last Job")); });
9.使用IoC容器:
public class ContainerJobActivator : JobActivator { private IContainer _container ; public ContainerJobActivator (IContainer container ) { _container = container ; }} public override object ActivateJob (Type type ) { return _container 。Resolve (type ); } }
在啓動Hangfire服務器以前將其註冊爲當前做業啓動器。
var container = new Container(); GlobalConfiguration.Configuration.UseActivator(new ContainerJobActivator(container)); ... app.UseHangfireServer();
Hangfire將做業保存到持久存儲中,並以可靠的方式處理它們。這意味着你能夠停止Hangfire工做線程,卸載應用程序域甚至終止進程,工做將被處理。Hangfire將做業標記爲已完成,只有當代碼的最後一行執行,並知道做業可能會失敗,最後一行。它包含不一樣的自動重試功能,能夠處理代碼中的存儲錯誤或錯誤。
上面介紹了Hangfire組件的經常使用方法,Hangfire組件的功能很是多,這裏就作介紹了,有興趣能夠去官網進行查看api。下面介紹一下Hangfire組件的一些核心對象,初探Hangfire組件深層次的問題。
1.RecurringJob.AddOrUpdate():
public static void AddOrUpdate( Expression<Action> methodCall, string cronExpression, TimeZoneInfo timeZone = null, string queue = EnqueuedState.DefaultQueue) { var job = Job.FromExpression(methodCall); var id = GetRecurringJobId(job); Instance.Value.AddOrUpdate(id, job, cronExpression, timeZone ?? TimeZoneInfo.Utc, queue); }
該方法用於按期做業在指定的CRON計劃上觸發屢次。該方法具備16個重載,Job.FromExpression(methodCall);用於獲取基於Job類的新實例給定的方法調用的表達式樹。GetRecurringJobId(job)方法根據Job對象獲取對應的JobID。
2.BackgroundJob.Enqueue():
public static string Enqueue([NotNull, InstantHandle] Expression<Action> methodCall) { var client = ClientFactory(); return client.Enqueue(methodCall); }
該方法基於給定的方法調用表達式建立一個新的fire-and-forget做業。該方法接受一個參數,表示將被編組到服務器的方法調用表達式。接下來咱們看一下var client = ClientFactory();方法的具體實現
internal static Func<IBackgroundJobClient> ClientFactory { get { lock (ClientFactoryLock) { return _clientFactory ?? DefaultFactory; } } set { lock (ClientFactoryLock) { _clientFactory = value; } } }
該屬性定義了一個Func<IBackgroundJobClient>的泛型委託。該屬性是一個可讀可寫的操做,對ClientFactoryLock加鎖,確保不發生死鎖狀況。
上面簡單的介紹了Hangfire組件的背景和一些簡單的應用,也着重的介紹了一些對象。這個組件的功能很強大,須要瞭解的地方也較多,這一篇文章不可能所有介紹,用作拋磚引玉的做用。在這裏吐槽一句,微軟最近技術發展太快,不少技術尚未來得及發展,就有新的技術出來,讓咱們這些底層的人着實難受,事物發展有規律,不是之前缺的東西能夠在很短的時間就能夠補上,仍是須要留下足夠的空間。