【转】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的解決思路是在執行真正的業務方法之前,通過將timer的duetime設為無限大,從而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(可以自定義實現從數據庫中讀取)取最多1000個BackgroundJobInfo,然后反射執行BackgroundJobInfo中定義的任務。
?
下面是一個ABP中通過BackgroundJobManager安排BackgroundJob的例子。
?
返回ABP源碼分析系列文章目錄
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【转】ABP源码分析九:后台工作任务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A股“涨停王”众泰汽车浴火重生!募资60
- 下一篇: 14寸!苹果史上最大iPad曝光:配置令