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

使用两个DbContext实例并行查询时触发ObjectDisposedException问题

问题原因与解决方案

核心问题

你遇到的ObjectDisposedException根本原因不是DbContext的线程安全问题,而是EF Core的延迟执行特性导致的:

  • ctx1.MyClass.Where(x => x.ID == id)返回的是IQueryable<MyClass>,这只是一个待执行的查询表达式,并没有真正发起数据库请求,也不是异步任务。
  • 当using块结束时,ctx1和ctx2会被立即释放,但此时你赋值给someData、someOtherData的只是未执行的查询。
  • 等到调用await Task.WhenAll(...)时,才会触发查询执行,但此时对应的DbContext已经被销毁,自然抛出上下文已释放的异常。

修复方案

要解决这个问题,必须在DbContext的using块内部,调用异步执行方法(比如ToListAsync())来启动查询任务,确保任务执行时上下文处于存活状态。修改后的代码如下:

Task<List<MyClass>> someDataTask;
Task<List<MyOtherClass>> someOtherDataTask;

using (MyContext ctx1 = new())
{
    // 在using块内调用ToListAsync,真正启动异步查询
    someDataTask = ctx1.MyClass.Where(x => x.ID == id).ToListAsync();
}

using (MyContext ctx2 = new())
{
    someOtherDataTask = ctx2.MyOtherClass.Where(x => x.ID == id).ToListAsync();
}

await Task.WhenAll(someDataTask, someOtherDataTask);

// 处理查询结果
var someData = someDataTask.Result;
var someOtherData = someOtherDataTask.Result;

额外说明

  • 你创建两个独立DbContext的思路是正确的,DbContext虽非线程安全,但这里每个任务对应各自的上下文实例,并行执行完全合法(只要每个上下文仅被一个线程操作)。
  • 记住EF Core中所有返回IQueryable的LINQ方法都是延迟执行的,只有调用ToListAsync()、FirstAsync()这类方法时,才会真正向数据库发送SQL请求。

内容的提问来源于stack exchange,提问作者WSC

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:17:32