ABP源碼分析九:后台工作任務


文主要說明ABP中后台工作者模塊(BackgroundWorker)的實現方式,和后台工作模塊(BackgroundJob)。ABP通過BackgroundWorkerManager來管理BackgroundJobManager,然后通過BackgroundJobManager來管理BackgroundJob。BackgroundJob就代表一個真正的后台任務。

 

這兩個模塊是在ABPKernelModule的PostInitialize完成初始化的。

 

后台工作者模塊

首先瀏覽下后台工作者模塊所涉及到的接口和類。其中BackgroundJobManager屬於后台工作模塊。其繼承自后台工作者模塊中的PeriodicBackgroundWorkerBase。

 

 

逐個分析這些類和接口

 

IRunnable/RunnableBase: 定義了啟動/終止一個任務的方法的接口和基本實現。共三個方法:start, stop, waittostop. start和stop這兩個方法很容易理解,就是啟動和終止一個任務。后文再解釋waittostop方法。

IBackgroundWorker:沒有添加任何新方法,這個接口僅用於標識其對應的實現是一個后台工作任務類,用於在后台執行一些任務。

BackgroundWorkerBase:實現IBackgroundWorker的一個抽象類,同時添加了UOW,Setting 和本地化的一些輔助方法。

IBackgroundWorkerManager/BackgroundWorkerManager: 用於管理后台工作任務 - IBackgroundWorker實例(添加IBackgroundWorker實例到管理器,啟動,終止和注銷后台任務)。設計一個***Manager接口和類是ABP中設計各個功能塊的慣用思路,起到了對外隱藏實現細節的作用,可以認為是Facade設計模式的運用。

 

 

PeriodicBackgroundWorkerBase:通過封裝AbpTimer實現定時啟動執行任務的功能。這個類型定義個一個抽象方法DoWork. AbpTimer最終會定時執行這個方法。

 

 

AbpTimer是整個ABP框架實現后台工作的核心類,其實現原理就是通過一個CLR中的timer定時啟動執行任務。這里有兩個要點值得留意:

第一,用timer有一個弊端,就是當timer間隔時間內,任務如果沒執行完,timer就會新建一個線程,從頭開始執行這個任務,而上一個線程仍然繼續執行,這樣就會導致系統中產生的線程過多,一會兒系統的資源就耗盡了。ABP的解決思路是在執行真正的業務方法之前,通過將timerduetime設為無限大,從而timer就失效了。業務方法執行完以后在恢復timer的設置。

 

第二,如何知道一個Timer真正結束了呢?也就是說如何知道一個Timer要執行的任務已經完成(這里定義為A效果),同時timer已失效(這里定義為B效果)ABP通過stop方法實現B,通過WaitToStop實現A效果。WaitToStop會一直阻塞調用他的線程直到_performingTasks變成false,也就是說Timer要執行的任務已經完成(任務完成時會將_performingTasks設為False,並且釋放鎖)。

 

 

 

 


后台工作模塊

首先瀏覽下涉及到的接口和類。

 

BackgroundJobInfo用於持久化job信息的實體類,對應於數據庫中的表AbpBackgroundJobs。這個實體類有以下屬性。一個job對應一個要執行的任務。他又兩個很關鍵的屬性JobArgs和JobType。其JobType就是接下來要介紹的IBackgroundJob實例的類型。IBackgroundJobManager最終就是根據這個JobType通過反射恢復出IBackgroundJob實例的。JobArgs就是傳入IBackgroundJob實例的Execute方法的實參(這里會被序列化后在賦值給BackgroundJobInfo)。

 

 

IBackgroundJob/BackgroundJob:定義一個后台工作任務的接口/和基本實現。具體的后台任務類可從BackgroundJob繼承,這是定義最終需要被執行的邏輯的地方。

IBackgroundJobConfiguration/BackgroundJobConfiguration: 配置是否激活后台工作任務功能。

 

BackgroundJobPriority后台job的優先級

 

IBackgroundJobStore/InMemoryBackgroundJobStore: 用於持久化后台任務BackgroundJobInfo。可以實現這個接口將后台任務BackgroundJobInfo存儲到數據庫。或者你可以使用module-zero,它已經實現了IBackgroundJobStore。如果你正在使用第三方的工作管理者(像Hangfire),那么不需要實現IBackgroundJobStore。

  

IBackgroundJobManager/BackgroundJobManager, IBackgroundJobManager默認是由BackgroundJobManager實現的。它可以被其他的后台工作提供者替代(Hangfire)。 BackgroundJobManager之所以能在后台執行任務,是因為其繼承了PeriodicBackgroundWorkerBase基類,並重寫了DoWork方法。

 

 

BackgroundJobManager:PeriodicBackgroundWorkerBase一個派生類,其具體實現了DoWork方法:從BackgroundJobStore(可以自定義實現從數據庫中讀取)取最多1000BackgroundJobInfo,然后反射執行BackgroundJobInfo中定義的任務。

 

下面是一個ABP中通過BackgroundJobManager安排BackgroundJob的例子。

 

返回ABP源碼分析系列文章目錄

 

 

 


免責聲明!

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



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