后台工作者HangFire与ABP框架Abp.Hangfire及扩展 (3)

IBackgroundJobManager由BackgroundJobManager默认实现。它可以被另一个后台作业提供者替代(参见 hangfire集成)。有关默认BackgroundJobManager的一些信息:
这是一个简单的作业队列在 单线程中作为FIFO使用。它使用IBackgroundJobStore来坚持作业。

它重试作业执行,直到作业 成功运行(不会抛出任何异常,但记录它们)或 超时。作业的默认超时时间为2天。

它成功执行时从商店(数据库)中删除作业。如果超时,则将其设置为废弃并保留在数据库中。

它越来越多地等待重新工作。等待1分钟第一次重试,2分钟第二次重试,4分钟第三次重试等等。

它以固定的时间间隔轮询商店的工作。按优先级(asc)查询作业,然后按try count(asc)进行排序。

后台工作存储

默认的BackgroundJobManager需要一个数据存储来保存和获取作业。如果您没有实现IBackgroundJobStore,那么它使用 InMemoryBackgroundJobStore,它不会将作业保存在持久数据库中。您可以简单地实现它来将作业存储在数据库中,或者可以使用 已经实现它的module-zero。
如果您使用第三方工作经理(如 Hanfgire),则无需实施IBackgroundJobStore。

配置

您可以在 模块的PreInitialize方法中使用Configuration.BackgroundJobs来配置后台作业系统。
禁用作业执行
您可能需要为应用程序禁用后台作业执行:

public class MyProjectWebModule : AbpModule { public override void PreInitialize() { Configuration.BackgroundJobs.IsJobExecutionEnabled = false; } //... } 这种情况很少见。但是,认为您正在同一个数据库上运行应用程序的多个实例(在Web场中)。在这种情况下,每个应用程序将查询作业的相同数据库并执行它们。这导致同一个工作的多个执行和一些其他问题。为了防止它,你有两个选择:

您只能为应用程序的一个实例启用作业执行。

您可以禁用所有Web应用程序实例的作业执行,并创建一个执行后台作业的独立应用程序(例如:Windows服务)。

异常处理

由于默认的后台作业管理器应该重新尝试失败的作业,它会处理(并记录)所有异常。如果你想在发生异常时得到通知,你可以创建一个事件处理程序来处理AbpHandledExceptionData。后台管理器用一个包装了真正异常的BackgroundJobException异常对象触发这个事件(对于实际的异常,得到InnerException)。

Hangfire集成

后台作业管理器被设计为可被另一个后台作业管理器替换。请参阅 Hangfire集成文档以用Hangfire替换它。

后台工作者与后台工作不同。它们是在后台运行的应用程序中的简单 独立线程。通常,他们定期执行一些任务。例子;

后台工作人员可以定期运行以 删除旧日志。

后台工作人员可以定期来 判断非活跃用户和发送电子邮件要返回给应用程序。

创建一个后台工作者

要创建一个后台工作者,我们应该实现 IBackgroundWorker接口。或者,我们可以根据我们的需要从BackgroundWorkerBase或PeriodicBackgroundWorkerBase继承 。
假设我们想在最近30天内没有登录到应用程序,使用户状态passive。看代码:

public class MakeInactiveUsersPassiveWorker : PeriodicBackgroundWorkerBase, ISingletonDependency { private readonly IRepository<User, long> _userRepository; public MakeInactiveUsersPassiveWorker(AbpTimer timer, IRepository<User, long> userRepository) : 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 oneMonthAgo = Clock.Now.Subtract(TimeSpan.FromDays(30)); var inactiveUsers = _userRepository.GetAllList(u => u.IsActive && ((u.LastLoginTime < oneMonthAgo && u.LastLoginTime != null) || (u.CreationTime < oneMonthAgo && u.LastLoginTime == null)) ); foreach (var inactiveUser in inactiveUsers) { inactiveUser.IsActive = false; Logger.Info(inactiveUser + " made passive since he/she did not login in last 30 days."); } CurrentUnitOfWork.SaveChanges(); } } } 这是现实的代码,可以直接在module-zero的 ASP.NET Boilerplate中运行 。

如果您从PeriodicBackgroundWorkerBase派生(如本示例中所示),则应该实施DoWork方法来执行您的定期工作代码。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssxgy.html