You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core中Startup与ConfigureServices间Logger被释放问题

问题原因

你在Startup构造函数中使用using var声明loggerFactory,该声明的作用域为当前构造函数代码块,构造函数执行完成后,loggerFactory会被立即自动释放。
你创建的StartupLogger实例依赖loggerFactory持有的所有日志提供器(包括EventLog日志提供器内部的EventLogInternal实例),loggerFactory释放时会连带销毁所有内部注册的日志提供器实例。当代码执行到ConfigureServices方法时,底层日志写入依赖的对象已经被释放,自然会抛出对象已释放的异常。

修复方案

方案1:持有LoggerFactory引用,延长其生命周期

将loggerFactory也定义为Startup类的实例字段,让它的生命周期和Startup实例保持一致,覆盖从构造函数执行到ConfigureServices调用的完整启动阶段,代码示例如下:

public class Startup
{
    private readonly ILoggerFactory _startupLoggerFactory;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        // 注意:这里不要加using关键字,避免提前释放
        _startupLoggerFactory = LoggerFactory.Create(builder =>
        {
            builder.SetMinimumLevel(LogLevel.Error);
            builder.AddEventLog(s =>
            {
                s.LogName = "MyLogName";
                s.SourceName = "MySource";
            });
            // 其他需要的持久化日志提供器
        });
        StartupLogger = _startupLoggerFactory.CreateLogger<Startup>();
    }

    public IConfiguration Configuration { get; }
    public ILogger StartupLogger { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // 此处调用日志写入不会再触发对象已释放异常
        StartupLogger.LogError("Failed to do something");
    }

    // 可选:Startup实例生命周期结束时手动释放日志工厂
    public void Dispose()
    {
        _startupLoggerFactory?.Dispose();
    }
}

方案2:使用主机内置的启动日志能力

ASP.NET Core 通用主机在构建阶段就已经初始化了基础日志能力,你不需要在Startup中手动创建LoggerFactory,可以直接在主机构建阶段获取日志实例传入Startup,完全不需要手动维护日志工厂的生命周期,日志配置也可以和应用运行阶段保持统一。

注意事项
  • 不要对生命周期长于当前代码块的依赖对象使用using声明,除非你明确控制对象的释放时机。
  • 如果启动阶段日志需要写入到和应用运行阶段相同的目标,建议直接在主机配置日志环节统一配置提供器,避免重复维护日志配置逻辑。

内容的提问来源于stack exchange,提问作者T.S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:27:20