.NET Core Web API中Autofac解析Cosmos DbContext时抛出已释放异常
问题排查:.NET Core Web API中EF Core操作Cosmos时Autofac生命周期异常
异常现象
在处理事务场景时,偶尔触发Autofac生命周期异常,提示:
无法从此LifetimeScope解析实例或创建嵌套生命周期,因为它(或其父级范围之一)已被释放。
异常抛出源为:
Autofac.Core.Lifetime.LifetimeScope.ThrowDisposedException
进一步排查发现,异常是EF Core尝试解析日志服务实例时触发,提示该服务已被释放。
相关代码
Cosmos上下文注册代码
services.AddDbContextFactory<MyDbContext>(optionsBuilder => optionsBuilder .UseCosmos( Configuration.GetSection(Constants.Cosmos).GetSection(Constants.AccountEndPoint).Value ?? throw new InvalidOperationException(), Configuration.GetSection(Constants.Cosmos).GetSection(Constants.AccountKey).Value ?? throw new InvalidOperationException(), Configuration.GetSection(Constants.Cosmos).GetSection(Constants.DatabaseName).Value ?? throw new InvalidOperationException(), options => { options.ConnectionMode(ConnectionMode.Direct); }));
触发异常的查询代码
public IEnumerable<string> GetMatchingRecords(params string[] recordIds) { using var context = _contextFactory.CreateDbContext(); var records = context.Records .Where(c => recordIds.Contains(c.RecordId)) .Select(c => c.RecordId) .AsNoTracking() .ToList(); return records; }
排查思路
- 检查异步操作中的上下文生命周期:若该查询被异步调用,确认没有在上下文
Dispose后访问延迟加载属性或其他EF相关资源,避免因异步回调导致的作用域过期。 - 验证Autofac与EF Core的作用域兼容性:
AddDbContextFactory默认创建独立作用域的上下文,检查自定义中间件或过滤器中是否存在过早释放请求作用域的逻辑,导致EF的日志工厂依赖的作用域被提前销毁。 - 排查日志服务的引用泄漏:即使未自定义日志生命周期,检查是否有代码手动持有日志服务实例的引用,导致作用域释放后仍被EF的
ScopedLoggerFactory调用。 - 梳理事务场景的作用域管理:异常在事务触发,确认事务操作是否在有效作用域内执行,比如是否在已释放的作用域中启动事务,或事务完成后未正确清理关联的EF资源。
- 启用EF Core详细日志:开启EF Core的Debug级别日志,跟踪
Microsoft.EntityFrameworkCore.Diagnostics.Internal.ScopedLoggerFactory.Create的调用时机,定位作用域被释放的具体节点。 - 检查Autofac服务注册的生命周期一致性:排查是否存在单例服务依赖作用域服务的情况,这类场景会导致作用域释放后,单例服务尝试访问已销毁的实例,进而引发连锁的生命周期异常。
内容的提问来源于stack exchange,提问作者Yan D
相关产品推荐
相关产品推荐

