ASP.NET Core 6 Web API调用AddAsync时抛出CLOIDataContext已释放异常
Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'CLOIDataContext'
我有一个ASP.NET Core 6 Web API,包含ContactController,该控制器调用ContactService,后者再调用仓储。在仓储的AddAsync方法执行_context.SaveChangesAsync()时抛出上述异常,未发现异常提示中的常见问题,相关代码配置如下:
Program.cs依赖注入配置
builder.Services.AddDbContext<CLOIDataContext>(options => options.UseSqlServer(connString)); builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>)); builder.Services.AddScoped<IContactService, ContactService>();
ContactController代码
[ApiController] [Route("[controller]/[action]")] public class ContactController : ControllerBase { private IContactService _contactService; private readonly CLOIDataContext _dataContext; public ContactController(CLOIDataContext dataContext, IContactService contactService) { _dataContext = dataContext; _contactService = contactService; } [HttpPost] public async Task<IActionResult> AddContact([FromBody] ContactDTO contact) { var results = _contactService.AddContact(contact); return Ok(results); } }
ContactService代码
public class ContactService : IContactService { private readonly IRepository<Contact> _contactRepository; private readonly IMapper _mapper; public ContactService(IRepository<Contact> contactRepository, IMapper mapper) { _contactRepository = contactRepository; _mapper = mapper; } public async Task<ContactDTO> AddContact(ContactDTO contactDTO) { var contact = _mapper.Map<Contact>(contactDTO); var id = await _contactRepository.AddAsync(contact); contactDTO.ID = id; return contactDTO; } }
Repository代码
public class Repository<T> : IRepository<T> where T : _ModelBase { private readonly DbContext _context; private readonly DbSet<T> _dbSet; public Repository(CLOIDataContext context) { _context = context; _dbSet = context.Set<T>(); } public async Task<int> AddAsync(T entity) { await _dbSet.AddAsync(entity); try { await _context.SaveChangesAsync(); //<=== 抛出异常处 } catch (Exception e) { throw e; } return entity.ID; } }
我怀疑该异常与DbContext或服务的注入方式有关,请问原因是什么?
问题核心是控制器未等待异步操作完成:
控制器的AddContact方法声明为async Task<IActionResult>,但调用_contactService.AddContact(contact)时未加await关键字,导致方法直接返回Ok(results),请求生命周期提前结束。ASP.NET Core会自动释放当前请求范围内的Scoped服务(包括CLOIDataContext),而AddContact内部的异步操作还在后台执行,当它尝试调用SaveChangesAsync时,DbContext已被释放,因此抛出异常。
修改方案
在控制器的AddContact方法中添加await,等待异步方法执行完成:
[HttpPost] public async Task<IActionResult> AddContact([FromBody] ContactDTO contact) { var results = await _contactService.AddContact(contact); return Ok(results); }
另外,控制器中注入的CLOIDataContext并未实际使用,可移除该注入避免冗余:
public class ContactController : ControllerBase { private readonly IContactService _contactService; public ContactController(IContactService contactService) { _contactService = contactService; } // ... 其他代码不变 }
补充说明
- ASP.NET Core中DbContext默认是Scoped生命周期,会在每个请求结束后被容器自动释放。
- 所有异步方法必须通过
await等待完成,否则会导致上下文提前释放,引发此类资源已释放异常。
内容的提问来源于stack exchange,提问作者CoderForHire

