.NET 框架通过 IHostedService 及其实现类 BackgroundService 为我们提供了后台服务的基础支持,但对于常见业务场景的基础设施支持仍显不足。本文将分三个迭代阶段,演示如何构建能安全运行周期性任务的守护型后台服务,最终实现企业级生产级别的解决方案。
dotnet new web
builder.Logging.AddSimpleConsole(c => c.SingleLine = true);
public interface IContinuousWorkIteration
{
Task Run(CancellationToken stoppingToken);
}
public class ContinuousBackgroundService<TIteration>(TIteration iteration)
: BackgroundService
where TIteration : IContinuousWorkIteration
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await iteration.Run(stoppingToken);
}
}
}
public static partial class Registration
{
public static IServiceCollection AddContinuousBackgroundService<TIteration>(this IServiceCollection services)
where TIteration : class, IContinuousWorkIteration
{
services.AddSingleton<TIteration>();
services.AddHostedService<ContinuousBackgroundService<TIteration>>();
return services;
}
}
public class MyIteration(ILogger<MyIteration> logger) : IContinuousWorkIteration
{
public async Task Run(CancellationToken stoppingToken)
{
logger.LogInformation("Running");
await Task.Delay(1000);
logger.LogInformation("Done");
}
}
builder.Services.AddContinuousBackgroundService<MyIteration>();
var builder = WebApplication.CreateBuilder(args);
// ...配置代码...
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
输出示例:
info: MyIteration[0]
Running
info: MyIteration[0]
Done
首版实现存在生命周期管理缺陷,当迭代器依赖 Scoped 服务(如数据库上下文)时会导致依赖注入异常。
public class ContinuousBackgroundService<TIteration>(IServiceScopeFactory scopeFactory)
: BackgroundService
where TIteration : IContinuousWorkIteration
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await using var scope = scopeFactory.CreateAsyncScope();
var iteration = scope.ServiceProvider.GetRequiredService<TIteration>();
await iteration.Run(stoppingToken);
}
}
}
services.AddScoped<TIteration>();
未处理的异常会导致整个后台服务崩溃,需要建立完善的容错机制。
public interface IContinuousWorkIteration
{
Task Run(CancellationToken stoppingToken);
abstract static Task OnException(Exception ex, ILogger logger);
}
public static async Task OnException(Exception ex, ILogger logger)
{
logger.LogError(ex, "An error occurred");
await Task.Delay(500);
}
public class ContinuousBackgroundService<TIteration>(IServiceScopeFactory scopeFactory, ILogger<TIteration> logger)
: BackgroundService
where TIteration : IContinuousWorkIteration
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
await using var scope = scopeFactory.CreateAsyncScope();
var iteration = scope.ServiceProvider.GetRequiredService<TIteration>();
await iteration.Run(stoppingToken);
}
catch (Exception ex)
{
await TIteration.OnException(ex, logger);
}
}
}
}
dotnet add package Backi.Continuous
public class MyIteration(ILogger<MyIteration> logger) : IContinuousWorkIteration
{
public static async Task OnException(Exception ex, ILogger logger)
{
logger.LogError(ex, "An error occurred");
await Task.Delay(500);
}
public async Task Run(CancellationToken stoppingToken)
{
logger.LogInformation("Running");
await Task.Delay(1000);
logger.LogInformation("Done");
}
}
services.AddContinuousBackgroundService<MyIteration>()
运行效果:
info: MyIteration[0]
Running
info: MyIteration[0]
Done
通过三个迭代阶段的演进,我们构建了具备以下特性的企业级后台服务框架: • 🔄 可靠的周期性执行机制 • 🎯 精准的生命周期管理 • 🛡️ 完善的异常防护体系 • ⚡ C#11 新特性加持
无论是微服务后台任务还是定时数据处理场景,这套方案都能提供稳定可靠的解决方案。