【.NET Core】Hangfire入门
中文文档:
https://www.mianshigee.com/tutorial/Hangfire-zh-official/readme.md
案例源码:
https://gitee.com/core-demo/hangfire
Demo
1、安装Nuget
添加数据库连接配置:
"ConnectionStrings": {
"DefaultConnection": "Data Source=xxxxx;User Id=root;Password=xxxxx;Database=hangfireDB;Port=3306;default command timeout=100;Connection Timeout=30;Charset=utf8mb4;Allow User Variables=true;IgnoreCommandTransaction=true"
}
2、Hangfire服务、中间件
using Hangfire;
using Hangfire.Dashboard.BasicAuthorization;
using Hangfire.MySql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
///
/// Hangfire扩展
///
public static class HangfireStartupExtensions
{
///
/// 注册Hangfire相关服务
///
///
///
public static void AddHangfire(this IServiceCollection services, string connectionString)
{
if (services == null) throw new ArgumentNullException(nameof(services));
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)//此方法 只初次创建数据库使用即可
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseStorage(new MySqlStorage(connectionString, new MySqlStorageOptions
{
TransactionIsolationLevel = (System.Transactions.IsolationLevel?)System.Data.IsolationLevel.ReadCommitted, //事务隔离级别。默认是读取已提交
QueuePollInterval = TimeSpan.FromSeconds(5), //- 作业队列轮询间隔。默认值为15秒。
JobExpirationCheckInterval = TimeSpan.FromHours(1),
CountersAggregateInterval = TimeSpan.FromMinutes(5),
PrepareSchemaIfNecessary = true, // 如果设置为true,则创建数据库表。默认是true
DashboardJobListLimit = 50000,
TransactionTimeout = TimeSpan.FromMinutes(1),
TablesPrefix = "Hangfire",
}))
.UseActivator(new JobActivator(services.BuildServiceProvider())));//依赖注入
services.AddHangfireServer();
}
///
/// 注册Hangfire中间件
///
///
public static void UseHangfire(this IApplicationBuilder app)
{
if (app == null) throw new ArgumentNullException(nameof(app));
//WorkerCount(默认20个):需要限制一下,否则会占用过多的数据库连接
app.UseHangfireServer(new BackgroundJobServerOptions { WorkerCount = 2 }); //配置服务
app.UseHangfireDashboard("/hangfire", DashboardOptions); //配置面板
}
private static DashboardOptions DashboardOptions
{
get
{
var filter = new BasicAuthAuthorizationFilter(
new BasicAuthAuthorizationFilterOptions
{
SslRedirect = false,
RequireSsl = false,
LoginCaseSensitive = false,
Users = new[]
{
new BasicAuthAuthorizationUser
{
Login = "fan", //可视化的登陆账号
PasswordClear = "123456" //可视化的密码
}
}
});
return new DashboardOptions
{
Authorization = new[] { filter }
};
}
}
}
3、JobActivator
Job是通过JobActivator创建,如果job依赖其他服务,需要重写JobActivator
///
/// Hangfire Job依赖注入
///
public class JobActivator : Hangfire.JobActivator
{
private IServiceProvider _serviceProvider;
public JobActivator(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public override object ActivateJob(Type type)
{
using var scope = _serviceProvider.CreateScope();
return scope.ServiceProvider.GetService(type);
}
}
4、注册服务、中间件
//ConfigureServices
services.AddHangfire(Configuration.GetConnectionString("DefaultConnection"));
//Configure
app.UseHangfire();
5、封装助手类,用户创建、删除周期任务
///
/// 后台任务操作
///
public interface IBackgroundJobManager
{
///
/// 创建周期性任务
///
///
///
void CreateRecurringJob(string jobID, string cronExp, Type jobType, MethodInfo jobMethod, params object[] args);
///
/// 删除任务
///
///
void DeleteJob(string jobID);
}
public class BackgroundJobManager : IBackgroundJobManager
{
public void CreateRecurringJob(string jobID, string cronExp, Type jobType, MethodInfo jobMethod, params object[] args)
{
var manager = new RecurringJobManager();
manager.AddOrUpdate(jobID, new Hangfire.Common.Job(jobType, jobMethod, args), cronExp);
}
public void DeleteJob(string jobID)
{
var manager = new RecurringJobManager();
manager.RemoveIfExists(jobID);
}
}
注册:
builder.Services.AddScoped();
6、客户端
public class HomeController : Controller
{
private readonly ILogger _logger;
private readonly IBackgroundJobManager _backgroundJobManager;
public HomeController(ILogger logger, IBackgroundJobManager backgroundJobManager)
{
_logger = logger;
_backgroundJobManager= backgroundJobManager;
}
public IActionResult Index()
{
return View();
}
///
/// 创建周期job
///
///
public IActionResult CreateJob()
{
var jobType = typeof(MyJob);
var jobMethod = jobType.GetMethod("ExecuteJob");
string cronExp = "0 */2 * * * ?";//每隔两分钟执行1次
_backgroundJobManager.CreateRecurringJob($"job-1", cronExp, jobType, jobMethod, 1);//最后一个参数是jobMethod的形参
return Content("success");
}
///
/// 删除job
///
///
public IActionResult DeleteJob()
{
_backgroundJobManager.DeleteJob($"job-1");
return Content("success");
}
}
7、job
public class MyJob
{
private readonly ILogger _logger;
public MyJob(ILogger logger)
{
_logger = logger;
}
public void ExecuteJob(int arg)
{
_logger.LogInformation($"执行job,参数:{arg}");
}
}
注册job:
builder.Services.AddScoped();
7、启动项目
查看Hangfire仪表盘:http://xxxx/hangfire
查看数据库,生成了如下表:
每隔两分钟,输出日志: