ABP Framework - 后台服务
后台服务
在ABP Framework中,后台分为作业和工作者,他们的不同点为:
- 作业
- 持久性的任务,可放在队列中执行。
- 失败后会继续重试
- 工作者
- 在后台运行的独立线程
- 定期运行
后台作业
依赖包:Volo.Abp.BackgroundJobs.Abstraction
创建后台作业
后台作业是通过实现IBackgroundJob<TArgs>
的现接口或继承自BackgroundJob<TArgs>
的类。在***.Application项目中添加StudentBackgroundJob
类
/// <summary>
/// 创建后台作业
/// </summary>
public class StudentBackgroundJob : BackgroundJob<Student>, ITransientDependency
{
/// <summary>
/// 实现Execute方法
/// 其中TArgs为Student实体类
/// </summary>
/// <param name="args"></param>
public override void Execute(Student args)
{
// 判断出生日期
if (DateTime.Now.Day == args.Brithday.Day &&
DateTime.Now.Month == args.Brithday.Month) {
args.Age += 1;
// 发送生日祝福
....
}
}
}
当作业在执行时出现异常,需抛出异常而不是将异常进行隐藏,因为抛出异常时系统会继续重试该作业,如果隐藏异常,系统会认为作业正常执行。
队列作业
作业代码完成后,需要通过队列的方式进行调用,此时可使用 IBackgroundJobManager
服务去管理队列。
public class RegistrationService:ApplicationService
{
private readonly IBackgroundJobManager _backgroundJobManager;
public RegistrationService(IBackgroundJobManager backgroundJobManager)
{
_backgroundJobManager = backgroundJobManager;
}
/// <summary>
/// 将要执行的任务放在队列中,然后进行作业
/// </summary>
/// <param name="student"></param>
/// <returns></returns>
public async Task RegisterAsync(Student student) {
await _backgroundJobManager.EnqueueAsync(student);
}
}
作业配置
[DependsOn(typeof(AbpBackgroundJobsModule))]
public class StopJobModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
// 禁用作业执行
Configure<AbpBackgroundJobOptions>(options =>
{
options.IsJobExecutionEnabled = false;
});
// 更改后台作业的的超时时间
Configure<AbpBackgroundJobWorkerOptions>(options =>
{
options.DefaultTimeout = 864000; //86400秒
});
}
}
后台工作者
继承BackgroundWorkerBase
类来创建一个后台工作者
public class MyWorker : BackgroundWorkerBase
{
public override Task StartAsync(CancellationToken cancellationToken = default)
{
//开始执行工作
}
public override Task StopAsync(CancellationToken cancellationToken = default)
{
//停止该工作
}
}
也可以使用AsyncPeriodicBackgroundWorkerBase
通过异步来完成后台工作
public class StudentLoggerWorker : AsyncPeriodicBackgroundWorkerBase
{
public StudentLoggerWorker(
AbpAsyncTimer timer,
IServiceScopeFactory serviceScopeFactory
) : base(
timer,
serviceScopeFactory)
{
Timer.Period = 1000; //1秒
}
protected override Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
Logger.LogInformation("工作者执行");
return Task.CompletedTask;
}
}
- 它需要实现
DoWorkAsync
方法执行定期任务. - 最好使用
PeriodicBackgroundWorkerContext
解析依赖 而不是构造函数. 因为AsyncPeriodicBackgroundWorkerBase
使用IServiceScope
在你的任务执行结束时会对其 disposed. AsyncPeriodicBackgroundWorkerBase
捕获并记录 由DoWorkAsync
方法抛出的 异常.
调用后台工作者
[DependsOn(typeof(AbpBackgroundWorkersModule))]
public class MyModule : AbpModule
{
public override async Task OnApplicationInitialization(
ApplicationInitializationContext context)
{
await context.AddBackgroundWorkerAsync<StudentLoggerWorker>();
}
}