ABP源码分析九:后台工做任务

文主要说明ABP中后台工做者模块(BackgroundWorker)的实现方式,和后台工做模块(BackgroundJob)。ABP经过BackgroundWorkerManager来管理BackgroundJobManager,而后经过BackgroundJobManager来管理BackgroundJob。BackgroundJob就表明一个真正的后台任务。html

 

这两个模块是在ABPKernelModule的PostInitialize完成初始化的。数据库

 

后台工做者模块设计模式

首先浏览下后台工做者模块所涉及到的接口和类。其中BackgroundJobManager属于后台工做模块。其继承自后台工做者模块中的PeriodicBackgroundWorkerBase。框架

 

 

逐个分析这些类和接口源码分析

 

IRunnable/RunnableBase: 定义了启动/终止一个任务的方法的接口和基本实现。共三个方法:start, stop, waittostop. start和stop这两个方法很容易理解,就是启动和终止一个任务。后文再解释waittostop方法。spa

IBackgroundWorker:没有添加任何新方法,这个接口仅用于标识其对应的实现是一个后台工做任务类,用于在后台执行一些任务。线程

BackgroundWorkerBase:实现IBackgroundWorker的一个抽象类,同时添加了UOW,Setting 和本地化的一些辅助方法。设计

IBackgroundWorkerManager/BackgroundWorkerManager: 用于管理后台工做任务 - IBackgroundWorker实例(添加IBackgroundWorker实例到管理器,启动,终止和注销后台任务)。设计一个***Manager接口和类是ABP中设计各个功能块的惯用思路,起到了对外隐藏实现细节的做用,能够认为是Facade设计模式的运用。3d

 

 

PeriodicBackgroundWorkerBase:经过封装AbpTimer实现定时启动执行任务的功能。这个类型定义个一个抽象方法DoWork. AbpTimer最终会定时执行这个方法。orm

 

 

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源码分析系列文章目录

相关文章
相关标签/搜索