Hangfire是一个强大的开源库,用于在.NET应用程序中执行后台作业。它提供了一种简单而有效的方式来处理各种类型的后台任务,如定时作业、延迟作业和重复作业等。本文将深入探讨Hangfire的特性,并通过多个实例演示其在C#项目中的应用。
使用NuGet包管理器安装Hangfire:
C#Install-Package Hangfire
对于SQL Server存储,还需要安装:
PowerShellInstall-Package Hangfire.SqlServer
在Program.cs
文件中配置Hangfire:
C#// 添加Hangfire服务
builder.Services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(_configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true
}));
// 添加Hangfire服务器
builder.Services.AddHangfireServer();
C#public class EmailService
{
public void SendWelcomeEmail(string email)
{
// 发送欢迎邮件的逻辑
Console.WriteLine($"Welcome email sent to {email}");
}
}
C#[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
[HttpPost]
public IActionResult Register(string email)
{
// 用户注册逻辑...
// 创建后台作业发送欢迎邮件
BackgroundJob.Enqueue<EmailService>(x => x.SendWelcomeEmail(email));
return Ok("User registered successfully");
}
}
C#public class ReminderService
{
public void SendReminder(int userId, string message)
{
// 发送提醒的逻辑
Console.WriteLine($"Reminder sent to user {userId}: {message}");
}
}
C#[Route("api/[controller]")]
[ApiController]
public class TaskController : ControllerBase
{
[HttpPost]
public IActionResult CreateTask(int userId, string taskDescription)
{
// 创建任务逻辑...
// 创建延迟作业,24小时后发送提醒
BackgroundJob.Schedule<ReminderService>(
x => x.SendReminder(userId, $"Don't forget your task: {taskDescription}"),
TimeSpan.FromHours(24));
return Ok("Task created and reminder scheduled");
}
}
C#public class DatabaseCleanupService
{
public void PerformCleanup()
{
// 数据库清理逻辑
Console.WriteLine("Database cleanup performed at: " + DateTime.Now);
}
}
Program.cs
C#// 在这里设置重复作业
using (var scope = app.Services.CreateScope())
{
var recurringJobManager = scope.ServiceProvider.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate<DatabaseCleanupService>(
"database-cleanup",
x => x.PerformCleanup(),
Cron.Daily);
}
这个例子展示了如何使用Hangfire处理大量数据,并报告进度。
C#public class BatchProcessingService
{
private readonly ILogger<BatchProcessingService> _logger;
public BatchProcessingService(ILogger<BatchProcessingService> logger)
{
_logger = logger;
}
public void ProcessLargeDataSet(int batchSize, int totalItems)
{
var batchCount = (int)Math.Ceiling((double)totalItems / batchSize);
for (int i = 0; i < batchCount; i++)
{
var batchNumber = i;
BackgroundJob.Enqueue(() => ProcessBatch(batchNumber, batchSize, totalItems));
}
}
public void ProcessBatch(int batchNumber, int batchSize, int totalItems)
{
var startIndex = batchNumber * batchSize;
var endIndex = Math.Min(startIndex + batchSize, totalItems);
for (int i = startIndex; i < endIndex; i++)
{
// 处理单个项目的逻辑
_logger.LogInformation($"Processing item {i}");
}
var progress = (int)((endIndex / (double)totalItems) * 100);
_logger.LogInformation($"Batch {batchNumber} completed. Overall progress: {progress}%");
}
}
C#[Route("api/[controller]")]
[ApiController]
public class DataProcessingController : ControllerBase
{
private readonly BatchProcessingService _batchProcessingService;
public DataProcessingController(BatchProcessingService batchProcessingService)
{
_batchProcessingService = batchProcessingService;
}
[HttpPost]
public IActionResult StartBatchProcessing()
{
BackgroundJob.Enqueue(() => _batchProcessingService.ProcessLargeDataSet(100, 10000));
return Ok("Batch processing started");
}
}
这个例子展示了如何使用Hangfire定期生成报告并通过邮件发送。
C#public interface IEmailService
{
void SendEmail(string recipient, string subject, string body);
}
public class EmailService : IEmailService
{
public void SendEmail(string recipient, string subject, string body)
{
// send an email
Console.WriteLine($"Email sent to {recipient} with subject: {subject}");
}
}
// Define the IReportGenerator interface
public interface IReportGenerator
{
string GenerateMonthlyReport();
}
// Implement the IReportGenerator interface
public class ReportGenerator : IReportGenerator
{
public string GenerateMonthlyReport()
{
return "This is the monthly report content.";
}
}
// The ReportingService class as defined
public class ReportingService
{
private readonly IEmailService _emailService;
private readonly IReportGenerator _reportGenerator;
private readonly IBackgroundJobClient _backgroundJobClient;
public ReportingService(IEmailService emailService, IReportGenerator reportGenerator, IBackgroundJobClient backgroundJobClient)
{
_emailService = emailService;
_reportGenerator = reportGenerator;
_backgroundJobClient = backgroundJobClient;
}
public void GenerateAndSendMonthlyReport()
{
var report = _reportGenerator.GenerateMonthlyReport();
var recipients = new[] { "manager@example.com", "director@example.com" };
foreach (var recipient in recipients)
{
_backgroundJobClient.Enqueue(() => _emailService.SendEmail(recipient, "Monthly Report", report));
}
}
}
C#// 在这里设置重复作业
using (var scope = app.Services.CreateScope())
{
var recurringJobManager = scope.ServiceProvider.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate<ReportingService>(
"monthly-report",
x => x.GenerateAndSendMonthlyReport(),
Cron.Monthly(1, 2)); //每月第一天凌晨2点
}
这个例子展示了如何使用Hangfire定期预热应用程序缓存。
C#public class CacheWarmupService
{
private readonly IMemoryCache _cache;
private readonly IProductRepository _productRepository;
public CacheWarmupService(IMemoryCache cache, IProductRepository productRepository)
{
_cache = cache;
_productRepository = productRepository;
}
public void WarmupProductCache()
{
var products = _productRepository.GetAllProducts();
foreach (var product in products)
{
_cache.Set($"product_{product.Id}", product, TimeSpan.FromHours(1));
}
Console.WriteLine($"Cache warmed up at {DateTime.Now}");
}
}
// 注册定时作业
using (var scope = app.Services.CreateScope())
{
var recurringJobManager = scope.ServiceProvider.GetRequiredService<IRecurringJobManager>();
recurringJobManager.AddOrUpdate<CacheWarmupService>(
"monthly-report",
x => x.WarmupProductCache(),
Cron.Hourly);
}
Hangfire为.NET开发者提供了一个强大而灵活的后台作业处理解决方案。通过本文的示例和最佳实践,你应该能够在自己的C#项目中有效地使用Hangfire来管理各种类型的后台任务。无论是简单的延迟作业还是复杂的重复任务,Hangfire都能满足你的需求,同时保证可靠性和可扩展性。
本文作者:rick
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!