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>();
    }
}
posted @ 2023-07-20 13:55  摧残一生  阅读(187)  评论(0编辑  收藏  举报