在asp.net core 6.0中使用Hangfire配置定时任务

为什么介绍Hangfire

我在一个我的简单地个人项目中需要用到用户请求限制,是根据分钟限制40个请求。这就要用到定时任务地库,很显然自己来写定时任务是不机智地做法。

我去问了gpt,他给了我几个库,我从后到前逐个看文档,发现比较复杂和麻烦,直到看见了这个,我较为容易地就在我的项目中配置了定时任务,而且很好的是,还有web ui控制面板。使用效果很好。

文档地址

官网地文档地址

如下

Documentation — Hangfire Documentation

ASP.NET Core Applications — Hangfire Documentation

不过可以在书栈网找到汉化(翻译)的文档。非常不错。

书栈网hangfire地址

https://www.bookstack.cn/read/hangfire-zh/blankquick-start

如何使用

简单地来说,你可以简单地按照官网来操作。 

ASP.NET Core Applications — Hangfire Documentation

 首先是你需要安装依赖包

你可以在nugut中手动安装,下面对应的包。

  <PackageReference Include="Hangfire.Core" Version="1.8.*" />
  <PackageReference Include="Hangfire.SqlServer" Version="1.8.*" />
  <PackageReference Include="Hangfire.AspNetCore" Version="1.8.*" />
  <PackageReference Include="Microsoft.Data.SqlClient" Version="*" />

不过一种更快速地方法是,手动编辑项目文件,然后保存即可。

vs 

双击要安装依赖包地项目

rider

编辑项目文件。

直接拷贝到一个ItemGroup中。

 然后保存(vs),即可。

然后创建数据库

这个根据需要即可,一般比较简单。数据库使用localdb和sql server均可。

只需要创建数据库即可,不需要创建数据表。

例如,下面

配置连接字符串。

在appsettings.json 中添加

"ConnectionStrings": {
  "HangfireConnection": "Server=127.0.0.1,1433;Database=HangfireJobs;MultipleActiveResultSets=True;User=suzumiya;Password=Sakura@99;TrustServerCertificate=true;"
}

Database按照自己创建的来写。用户名和密码也按照自己的。

此外,你还需要配置数据库的tcp/ip连接。或者你可以使用windows身份验证的连接字符串。

例如

"ConnectionStrings": {
  "HangfireConnection": "Server=DESKTOP-6ACSBNS;Database=HangfireJobs;MultipleActiveResultSets=True;Integrated Security=True;TrustServerCertificate=true;"
}

其中的Server要填写连接Sql server时用到的服务器名称(不具备迁移性)。

编辑Program.cs文件进行配置。

using Hangfire;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
// 进行基本配置,注意其中的HangfireConnection需要和前面的数据库连接字符串的名字一样。
builder.Services.AddHangfire(configuration => configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection")));

// 配置服务

builder.Services.AddHangfireServer();

var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
// 默认情况下,仅允许本地访问 Hangfire 仪表板。必须配置仪表板授权才能允许远程访问
// 这里添加了一个连接地址,表明使用新的地址进行访问,而不是默认地址。
//默认地址是hangfire
app.UseHangfireDashboard("/dashboard");


app.UseRouting();

app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapDefaultControllerRoute();
// Map hangfire的端点
    endpoints.MapHangfireDashboard();
});
app.Run();

 启动程序,可以直接访问。

 配置任务

在前面,我们已经能够访问仪表盘,这就意味着我们完成了最基本的架构,紧接着我们就可以在这个框架上进行配置任务进行使用了。

配置入门任务(单次执行)

 在app.run();前面添加下面的代码。

var backgroundJobs = app.Services.GetRequiredService<IBackgroundJobClient>();
backgroundJobs.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));

// RecurringJob
app.Run();

不过,直接使用 

BackgroundJob.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));

也是可以的,因为BackgroundJob.Enqueue是一个静态方法。

启动程序,观察效果。

注意,启动程序时选择和项目同名的自托管的方式。可以观察到输出。(配置的任务一般不会是控制台输出)。

 可以在最后一行看到 Hello world from Hangfire!

 同时在

 

/dashboard/jobs/succeeded

看到已经完成的任务。

 文档

阅读文档地址,可以使用更多细节。

https://docs.hangfire.io/en/latest/background-methods/index.html

后台任务

HelloMaker

public class HelloMaker
{
    private readonly string? _name;

    public HelloMaker()
    {

    }
    public HelloMaker(string? name)
    {
        _name = name;
    }

    public void Joker()
    {
        Console.WriteLine(_name+" Ha haha!");
    }
}

配置后台任务

backgroundJobs.Enqueue<HelloMaker>(maker => maker.Joker());

启动

我们可以 观察到两个输出,这是因为前面我没有添加空构造函数。

任务被存储,然后又在配置好后重新运行。

 单击#6对应的作业

可以在里面找到错误信息。

 延迟任务

官网比较详细,不再过多介绍

使用代码

BackgroundJob.Enqueue<HelloMaker>(maker => maker.Joker());
BackgroundJob.Schedule<HelloMaker>(maker => maker.Joker(),TimeSpan.FromSeconds(2));

修改前面的HelloMaker对象(需要配置为单例)

public void Joker()
{
    Console.WriteLine(_name+" Ha haha!"+DateTime.Now);
}

执行,可以看到下面的输出

Ha haha!2023/8/27 20:38:00
 Ha haha!2023/8/27 20:38:15

 有点怪异,配置的延迟2秒,实际执行延迟了那么多。

查看时发现,只能认为是可接受的。 

重复任务

代码

RecurringJob.AddOrUpdate("joker", ()=>
new HelloMaker("John").Joker(),Cron.Minutely);

一个遗憾是最低只能配置按分钟执行的作业/任务。

输出:

 Ha haha!2023/8/27 20:55:06
 Ha haha!2023/8/27 20:56:06

并没有发现John的身影。

添加默认值

public HelloMaker()
{
    _name = "default";
}

之后,效果是这样的。(手动执行)

default Ha haha!2023/8/27 20:58:55
default Ha haha!2023/8/27 20:58:56
default Ha haha!2023/8/27 20:59:01

虽然每个对象都是新的,我期望他会使用构造函数提供的值,他却没有。

可以在

Calling Methods in Background — Hangfire Documentation

看到它的工作流程。

使用依赖注入

一个很尴尬的事情是,hangfire的asp.net core的包使用的就是asp.net 的容器进行依赖注入,我反而去hangfire找了很久其他的容器。最终找到了一个可用的容器。但是我把那个取消之后发现依旧可用。

所以依赖注入直接按照asp.net core的规则即可。例如 

RecurringJob.AddOrUpdate<HelloMaker>("newMaker",hel=>hel.Joker(),Cron.Minutely);

 到了事件后就会自动从容器中找一个对象然后执行。

一个作业(任务)是什么样的?

using HangfireHub.Models;

var helloMaker = Activate<HelloMaker>();

helloMaker.Joker();

Activate 就像一个 

app.Services.GetRequiredService<T>()一样 /单例app.Services.CreateScope().ServiceProvider.GetRequiredService<>()作用域

会在到达要执行的时间时创建(获取)执行。

扩展

另外的容器。

GitHub - CodeAnimal/Ninject.Extensions.DependencyInjection: Ninject integration of the the .NET Core dependency injection abstraction.

添加一些代码,像下面一样即可。

需要的依赖是

        <PackageReference Include="Ninject" Version="3.3.6" />
        <PackageReference Include="Ninject.Extensions.DependencyInjection" Version="1.0.2" />

这实际上就是更换了asp.net core 提供的默认容器。

不仅可以在 kernel => 后面绑定依赖关系

还可以使用asp.net core的AddSingleton等方法。

using Hangfire;
using HangfireHub.Hangfire;
using HangfireHub.Models;
using Ninject;
using Ninject.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);
builder.Host
    .UseServiceProviderFactory(new NinjectServiceProviderFactory())
    .ConfigureContainer<IKernel>(kernel =>
    {
        kernel.Bind<Dog>().ToSelf();
        kernel.Bind<Sound>().ToSelf().InSingletonScope();
    });


builder.Services.AddControllersWithViews();
builder.Services.AddHangfire(configuration => configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection")));

builder.Services.AddHangfireServer();

builder.Services.AddSingleton<HelloMaker>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseHangfireDashboard("/dashboard");


app.UseRouting();

app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapHangfireDashboard();
    endpoints.MapDefaultControllerRoute();
});


var maker = app.Services.GetRequiredService<HelloMaker>();
maker.Prefix = "PPP: ";
// RecurringJob.AddOrUpdate<Dog>("hub",dog=>dog.WW(),Cron.Minutely);
RecurringJob.AddOrUpdate<HelloMaker>("newMaker",hel=>hel.Joker(),Cron.Minutely);
// RecurringJob
app.Run();

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫叶kx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值