后台任务

比较耗时的需求可以这样解决

后台工作(Background job)

1.创建一个后台job  

public class TestJob : BackgroundJob<int>, ITransientDependency
{
  [UnitOfWork]
public override void Execute(int number) { Logger.Debug(number.ToString()); } }

可以注入并使用 IBackgroundJobManager将作业添加到队列中

public class MyService
{
    private readonly IBackgroundJobManager _backgroundJobManager;

    public MyService(IBackgroundJobManager backgroundJobManager)
    {
        _backgroundJobManager = backgroundJobManager;
    }

    public void Test()
    {
        _backgroundJobManager.Enqueue<TestJob, int>(42);
    }
}

通过MyService调用   在其他Task接口中    调用Test() 有时候会出现当前作业执行失败的情况  不清楚为什么

    public class MyServiceAppService : ApplicationService, IMyServiceAppService
    {
        private readonly IBackgroundJobManager _backgroundJobManager;

        public MyServiceAppService(IBackgroundJobManager backgroundJobManager)
        {
            this._backgroundJobManager = backgroundJobManager;
        }
        public void SendJob()
        {
            MyService myService = new MyService(_backgroundJobManager);
            myService.Test();
        }
        public async Task SendJobAsync()
        {
            MyService myService = new MyService(_backgroundJobManager);
            myService.Test();
            await Task.FromResult(0);
        }
    }

*********************

后台工作者(Background workers)

它们是在后台运行的应用程序中的简单 独立线程。通常,它们会定期运行以执行某些任务

1.创建后台定时运行任务

    public class MakeInactiveUsersPassiveWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
    {
        private readonly IRepository<Customer, Guid> _customerRepository;

        public MakeInactiveUsersPassiveWorker(AbpTimer timer,
            IRepository<Customer, Guid> customerRepository
            )
            : base(timer)
        {
            _userRepository = userRepository;
            Timer.Period = 5000; //5 seconds (good for tests, but normally will be more)
        }

        [UnitOfWork]
        protected override void DoWork()
        {
            //using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant))
            //{var inactiveUsers = _customerRepository.GetAll().IgnoreQueryFilters().Where(t => t.IsSystem != true).ToList();

            foreach (var inactiveUser in inactiveUsers)
            {
                Logger.Info(inactiveUser.Name + " :这个用户不是系统创建的");
            }
            Logger.Info( " :这个用户不是系统创建的");

                CurrentUnitOfWork.SaveChanges();
            //}
        }
    }

2.在模块的预初始化中注册

    public override void PostInitialize()
    {
        var workManager = IocManager.Resolve<IBackgroundWorkerManager>();
        workManager.Add(IocManager.Resolve<MakeInactiveUsersPassiveWorker>());
    }

3.注意: 这个后台工作者中注入了_customerRepository这个仓储     所以在模块的预初始化中解析MakeInactiveUsersPassiveWorker需要在注入仓储之后 ,   后台工作者在application和code的module中注入是无效的  因为这两个模块的时候还没有注入仓储   可以考虑把这两行代码放在Web.Core的初始化方法中或者其他地方

**************************

通过Hangfire替换ABP默认后台作业管理器

1.安装

Abp.HangFire.AspNetCore      Hangfire.SqlServer

2.更改Startup类以将Hangfire添加到依赖项注入,然后在ConfigureServices方法中配置存储和连接字符串 

services.AddHangfire(config =>
{
    config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
});

3.然后,我们在Configure方法中添加UseHangfireServer调用

app.UseHangfireServer();

启动仪表盘  

app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
    //Authorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") }
});

4.配置我们的Web模块来替换ABP的默认后台作业管理器的Hangfire:

[DependsOn(typeof (AbpHangfireAspNetCoreModule))]
public class MyProjectWebModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.BackgroundJobs.UseHangfire();             
    }

    //...
}

5.如果报错

 检查上面两个安装的包的版本   安装这两个包版本对不上没有自动抛异常        需要自己手动检查

所有的后台任务会在/Hangfire展示

后台任务    在ABP模块进行初始化的时候  会初始化一个后台JOB对象放到workerManager 中     workerManager这个对象里面就是存放后台job对象和所有的后台工作者对象

                var workerManager = IocManager.Resolve<IBackgroundWorkerManager>();
                workerManager.Start();
                workerManager.Add(IocManager.Resolve<IBackgroundJobManager>());
            }

后台任务和后台工作者最后都会包成一个PeriodicBackgroundWorkerBase对象     定时的执行周期任务都是通过.net下的Timer对象来实现     ABP包了一层AbpTimer      解决第一次任务未执行完毕  第二次任务就启动的问题

ABP在执行当前后台任务的时候     会把执行周期设置为无限大       等执行完毕      在把执行周期置为用户设定的时间(确保执行第二次后台任务,第一次已经执行完毕)    

在BackgroundJobManager中的DoWork()方法中就是根据条件获取后台job任务     执行包装好的业务代码

后台任务最后会转成一个PeriodicBackgroundWorkerBase对象   默认周期5秒钟

后台工作者     需要自己在module中注册到workerManager 中   每一个后台工作者都是一个单独的线程

原文地址:https://www.cnblogs.com/jiangchengbiao/p/10748735.html