.NET 深度实践:打造安全可靠的全周期后台服务引擎

作者:微信公众号:【架构师老卢】
4-4 20:19
56

.NET 框架通过 IHostedService 及其实现类 BackgroundService 为我们提供了后台服务的基础支持,但对于常见业务场景的基础设施支持仍显不足。本文将分三个迭代阶段,演示如何构建能安全运行周期性任务的守护型后台服务,最终实现企业级生产级别的解决方案。


First Implementation: Singleton-Based Iteration

环境准备

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

Second Iteration: Applying Scoped Lifecycle for the Iteration

问题诊断

首版实现存在生命周期管理缺陷,当迭代器依赖 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>();

Final Iteration: Making Iterations Safe with Exception Handling

核心痛点

未处理的异常会导致整个后台服务崩溃,需要建立完善的容错机制。

C#11 新特性应用

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);
            }
        }
    }
}

TL;DR 极速上手指南

  1. 安装 NuGet 包:
dotnet add package Backi.Continuous
  1. 实现业务逻辑:
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");
    }
}
  1. 服务注册:
services.AddContinuousBackgroundService<MyIteration>()

运行效果

info: MyIteration[0]
      Running
info: MyIteration[0]
      Done

通过三个迭代阶段的演进,我们构建了具备以下特性的企业级后台服务框架: • 🔄 可靠的周期性执行机制 • 🎯 精准的生命周期管理 • 🛡️ 完善的异常防护体系 • ⚡ C#11 新特性加持

无论是微服务后台任务还是定时数据处理场景,这套方案都能提供稳定可靠的解决方案。

相关留言评论
昵称:
邮箱:
阅读排行