ä¸æææ¡£ï¼
https://www.mianshigee.com/tutorial/Hangfire-zh-official/readme.md
æ¡ä¾æºç ï¼
https://gitee.com/core-demo/hangfire
Demo
1ãå®è£ Nuget
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.28" />
<PackageReference Include="Hangfire.Core" Version="1.7.28" />
<PackageReference Include="Hangfire.Dashboard.BasicAuthorization" Version="1.0.2" />
<PackageReference Include="Hangfire.MySqlStorage" Version="2.0.3" />
æ·»å æ°æ®åºè¿æ¥é ç½®ï¼
"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;
/// <summary>
///Â Hangfireæ©å±
/// </summary>
public static class HangfireStartupExtensions
{
/// <summary>
/// 注åHangfireç¸å
³æå¡
/// </summary>
/// <param name="services"></param>
/// <param name="connectionString"></param>
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();
}
/// <summary>
/// 注åHangfireä¸é´ä»¶
/// </summary>
/// <param name="app"></param>
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
/// <summary>
/// Hangfire Jobä¾èµæ³¨å
¥
/// </summary>
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ãå°è£ å©æç±»ï¼ç¨æ·å建ãå é¤å¨æä»»å¡
/// <summary>
/// åå°ä»»å¡æä½
/// </summary>
public interface IBackgroundJobManager
{
/// <summary>
/// å建å¨ææ§ä»»å¡
/// </summary>
/// <param name="jobID"></param>
/// <param name="cronExp"></param>
void CreateRecurringJob(string jobID, string cronExp, Type jobType, MethodInfo jobMethod, params object[] args);
/// <summary>
/// å é¤ä»»å¡
/// </summary>
/// <param name="jobID"></param>
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<IBackgroundJobManager, BackgroundJobManager>();
6ã客æ·ç«¯
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IBackgroundJobManager _backgroundJobManager;
public HomeController(ILogger<HomeController> logger, IBackgroundJobManager backgroundJobManager)
{
_logger = logger;
_backgroundJobManager= backgroundJobManager;
}
public IActionResult Index()
{
return View();
}
/// <summary>
/// å建å¨æjob
/// </summary>
/// <returns></returns>
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");
}
/// <summary>
/// å é¤job
/// </summary>
/// <returns></returns>
public IActionResult DeleteJob()
{
_backgroundJobManager.DeleteJob($"job-1");
return Content("success");
}
}
7ãjob
public class MyJob
{
private readonly ILogger<MyJob> _logger;
public MyJob(ILogger<MyJob> logger)
{
_logger = logger;
}
public void ExecuteJob(int arg)
{
_logger.LogInformation($"æ§è¡jobï¼åæ°ï¼{arg}");
}
}
注åjobï¼
builder.Services.AddScoped<MyJob>();
7ãå¯å¨é¡¹ç®
æ¥çHangfire仪表çï¼http://xxxx/hangfire
æ¥çæ°æ®åºï¼çæäºå¦ä¸è¡¨ï¼
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iNwgjN4QjNzcTMtkTO3YDM4MzMyMjM1AjMyAjMtkjM2QDOx8CX1AjMyAjMvwVOyYDN4EzLcd2bsJ2Lc12bj5ycn9Gbi52YuIjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
æ¯é两åéï¼è¾åºæ¥å¿ï¼