步骤:
1:安装nuget包: Abp.HangFire.AspNetCore ,Hangfire.MemoryStorage, Hangfire.PostgreSql【本人使用【postgresql】数据库包】
图:
2: Startup中代码:
在这个ConfigureServices方法中添加:
#region Hangfire
services.HangfireServices(_appConfiguration);
#endregion
在这个Configure方法中添加:
#region Hangfirst
app.ToUseHangfireServer(_appConfiguration);
#endregion
图:
2-1:HangfireServices内部代码:
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.MemoryStorage;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace SamsinoYard.Web.Host.hangfrie
{
public static class HangfireSetup
{
public static IServiceCollection HangfireServices(this IServiceCollection services, IConfiguration configuration)
{
//GlobalStateHandlers.Handlers.Add(new SucceededStateExpireHandler(int.Parse(configuration["Hangfire:JobExpirationTimeout"])));
services.AddHangfire(config =>
{
/* //使用PostgreSql存储*/
var connectionString = configuration["ConnectionStrings:Default"];
// 启用SSL Enabling SSL support
// config.UsePostgreSqlStorage(new DefaultConnectionBuilder(
//options.HangfireDatabaseConnectionString,
//connection =>
//{
// connection.ProvideClientCertificatesCallback += clientCerts =>
// {
// clientCerts.Add(X509Certificate.CreateFromCertFile("[CERT_FILENAME]"));
// };
//}));
config.UsePostgreSqlStorage(connectionString, new PostgreSqlStorageOptions
{
QueuePollInterval = TimeSpan.FromSeconds(15.0), //队列轮询间隔
InvisibilityTimeout = TimeSpan.FromMinutes(30.0),// 隐形超时
DistributedLockTimeout = TimeSpan.FromMinutes(10.0),//分布式锁超时
TransactionSynchronisationTimeout = TimeSpan.FromMilliseconds(500.0), //事务同步超时
JobExpirationCheckInterval = TimeSpan.FromHours(1.0), //作业到期检查间隔
SchemaName = "hangfire",
UseNativeDatabaseTransactions = true,
PrepareSchemaIfNecessary = true, //如果需要准备架构
DeleteExpiredBatchSize = 1000 //删除过期批次大小
});
//config.UseStorage(new MemoryStorage(
// new MemoryStorageOptions
// {
// JobExpirationCheckInterval = TimeSpan.FromHours(1), //- 作业到期检查间隔(管理过期记录)。默认值为1小时。
// CountersAggregateInterval = TimeSpan.FromMinutes(5), //- 聚合计数器的间隔。默认为5分钟。
// }
//));
//config.UseDashboardMetric(DashboardMetrics.ServerCount)
// .UseDashboardMetric(DashboardMetrics.RecurringJobCount)
// .UseDashboardMetric(DashboardMetrics.RetriesCount)
// .UseDashboardMetric(DashboardMetrics.AwaitingCount)
// .UseDashboardMetric(DashboardMetrics.EnqueuedAndQueueCount)
// .UseDashboardMetric(DashboardMetrics.ScheduledCount)
// .UseDashboardMetric(DashboardMetrics.ProcessingCount)
// .UseDashboardMetric(DashboardMetrics.SucceededCount)
// .UseDashboardMetric(DashboardMetrics.FailedCount)
// .UseDashboardMetric(DashboardMetrics.EnqueuedCountOrNull)
// .UseDashboardMetric(DashboardMetrics.FailedCountOrNull)
// .UseDashboardMetric(DashboardMetrics.DeletedCount);
});
services.AddHostedService<RecurringJobsService>();
var jobOptions = new BackgroundJobServerOptions
{
Queues = new string[] { "xiaomi_01", "alpha", "beta", "default" },
//WorkerCount = Environment.ProcessorCount * int.Parse(configuration["Hangfire:ProcessorCount"]),// 默认20
//ServerName = configuration["Hangfire:ServerName"],
//SchedulePollingInterval = TimeSpan.FromSeconds(30), //计划轮询间隔 支持任务到秒
};
services.AddHangfireServer(options =>
{
options = jobOptions;
});
return services;
}
public static void ToUseHangfireServer(this IApplicationBuilder app, IConfiguration configuration)
{
app.UseHangfireDashboard(configuration["Hangfire:DashboardPath"], new DashboardOptions
{
//Authorization = new[]
//{
// new AbpHangfireAuthorizationFilter("")
//},
// Authorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") }
});
//var jobOptions = new BackgroundJobServerOptions
//{
// Queues = new[] { "critical", "test", "default" },
// WorkerCount = Environment.ProcessorCount * int.Parse(configuration["Hangfire:ProcessorCount"]),
// ServerName = configuration["Hangfire:ServerName"],
// SchedulePollingInterval = TimeSpan.FromSeconds(30), //计划轮询间隔 支持任务到秒
//};
// app.UseHangfireServer();
}
}
}
图:
public class RecurringJobsService : BackgroundService
{
private readonly IBackgroundJobClient _backgroundJobs;
private readonly IRecurringJobManager _recurringJobs;
private readonly ILogger<RecurringJobScheduler> _logger;
public RecurringJobsService(
IBackgroundJobClient backgroundJobs,
IRecurringJobManager recurringJobs,
ILogger<RecurringJobScheduler> logger)
{
_backgroundJobs = backgroundJobs ?? throw new ArgumentNullException(nameof(backgroundJobs));
_recurringJobs = recurringJobs ?? throw new ArgumentNullException(nameof(recurringJobs));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// 统一执行
/// </summary>
/// <param name="stoppingToken"></param>
/// <returns></returns>
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
_recurringJobs.AddOrUpdate<ISendMessage>("Send", x => x.Send("添加一个周期性作业"), Cron.Minutely(), TimeZoneInfo.Local);
_recurringJobs.AddOrUpdate<ISendMessage>("GetAllCoalTypeName", x => x.GetAllCoalTypeName("获取最后一个名称"), Cron.Minutely(), TimeZoneInfo.Local);
// Thread.Sleep(TimeSpan.FromMinutes(2));
}
catch (Exception e)
{
_logger.LogError("An exception occurred while creating recurring jobs.", e);
}
//Task.Delay(TimeSpan.FromMinutes(2));
return Task.CompletedTask;
}
}
图:
图二:执行个人业务任务实例;
结果如下图:
个人本地地址:无授权情况下的结果;
推荐查看官方文档:https://docs.hangfire.io/en/latest/getting-started/index.html
简单使用介绍:
1、 基于队列的任务处理(Fire-and-forget)
延迟作业也只执行一次,但不会立即执行 - 只能在指定的时间间隔后执行。
var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
2、定时执行(Recurring)
按照指定的CRON计划, 重复执行的作业会被多次触发。
RecurringJob.AddOrUpdate( () => Console.WriteLine("Recurring!"), Cron.Daily);
3、延续性执行(Continuations)
延续性任务类似于.NET中的Task,可以在第一个任务执行完之后紧接着再次执行另外的任务:
BackgroundJob.ContinueWith( jobId, () => Console.WriteLine("Continuation!"));
4、延时执行任务(Delayed)
延迟作业也只执行一次,但不会立即执行 - 只能在指定的时间间隔后执行。
var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
5、批处理(Batches)
批处理是一组自动创建的后台作业。
var batchId = Batch.StartNew(x => { x.Enqueue(() => Console.WriteLine("Job 1")); x.Enqueue(() => Console.WriteLine("Job 2")); });
6、延时批处理(Batch Continuations)
批处理在父类完成后触发后台作业。
Batch.ContinueWith(batchId, x => { x.Enqueue(() => Console.WriteLine("Last Job")); });
7、后台进程(Background Process)
当你需要在应用程序的整个生命周期中连续运行后台进程时使用它们。
public class CleanTempDirectoryProcess : IBackgroundProcess { public void Execute(BackgroundProcessContext context) { Directory.CleanUp(Directory.GetTempDirectory()); context.Wait(TimeSpan.FromHours(1)); } }