Asp-Net-Core开发笔记:集成Hangfire实现异步任务队列和定时任务( 二 )

添加中间件:
app.UseHangfireDashboard();简单使用Hangfire 注册的时候默认是单例模式,所以在任意代码中使用其静态方法就能添加异步任务或者定时任务 。
异步任务:
BackgroundJobs.Enqueue(() => Console.WriteLine("Hello world!"));定时任务:
Hangfire的定时任务叫做 recurrent tasks,我之前一般习惯叫 scheduled task,一开始差点找不到文档~
以下代码添加一个每天执行一次的任务,如果需要其他时间,可以自定义后面的 Cron 参数,具体自行研究 Cron 语法~
RecurringJob.AddOrUpdate("easyjob", () => Console.Write("Easy!"), Cron.Daily);正经使用OK,终于进到正文
正如我一开始说的,前面介绍的用法是远远不够的,如果只是介绍个 Hello World,那也没必要专门写篇文章了…
现在开始介绍如何将 Hangfire 结合我的 CrawlService 使用
因为 CrawlService 需要操作数据库,所以是用到了依赖注入的,所以我们需要让 Hangfire 也支持依赖注入 。
官方文档有一小节是关于 IOC 容器的(https://docs.hangfire.io/en/latest/background-methods/using-ioc-containers.html),不过并没有介绍 AspNetCore 的容器,直接自己动手 丰衣足食咯~
添加 AspNetCore 的依赖注入容器一开始搜了好久没找到,最终是在Github上找到一个例子代码,里面的 AspNetCore 版本好老,居然是1.1版本,我都没用过… 不过并不影响我节俭他的写法~
这一步需要 JobActivator 的子类
来写一个,我把它放在 Infrastructure 目录下
using Hangfire;public class HangfireActivator : JobActivator {private readonly IServiceProvider _serviceProvider;public HangfireActivator(IServiceProvider serviceProvider) {_serviceProvider = serviceProvider;}public override object? ActivateJob(Type jobType) {return _serviceProvider.GetService(jobType);}}这里是在 HangfireActivator 的构造函数中把 AspNetCore 的 IOC 容器对象传入,并且重写 ActivateJob 方法,让 Hangfire 才激活任务的时候从 IOC 容器中获取对象,比较好理解 。
修改服务注册代码其实服务注册部分是一样的,无须修改
不过按照习惯,为了使 Program.cs 或者 Startup.cs 代码比较简洁,我还是写了扩展方法来实现这部分 。
Extensions 目录中添加 ConfigureHangfire.cs
public static class ConfigureHangfire {public static void AddHangfirePkg(this IServiceCollection services, IConfiguration configuration) {services.AddHangfire(conf => conf.SetDataCompatibilityLevel(CompatibilityLevel.Version_170).UseSimpleAssemblyNameTypeSerializer().UseRecommendedSerializerSettings().UseRedisStorage());services.AddHangfireServer();}public static void UseHangfire(this WebApplication app) {GlobalConfiguration.Configuration.UseActivator(new HangfireActivator(app.Services));app.UseHangfireDashboard();}}可以看到有修改的地方就是在添加中间件之前,配置了 Activator 这行代码:
GlobalConfiguration.Configuration.UseActivator(new HangfireActivator(app.Services));直接把 IOC 容器传入
搞定~
接着在 Program.cs (我用的 .Net6)中使用这个扩展方法就完事了~
builder.Services.AddHangfirePkg(builder.Configuration);// 中间件app.UseHangfire();创建任务有了依赖注入之后,创建异步任务是这样的 。也就是多了个泛型参数 。
BackgroundJob.Enqueue<CrawlService>(a => a.CrawlAllProc());定时任务,每小时执行一次
RecurringJob.AddOrUpdate<CrawlService>(a => a.CrawlAllProc(), Cron.Hourly);改造一下数据采集代码OK,最后回到一开始的数据采集代码,做如下修改:

经验总结扩展阅读