我正在使用 EF 的异步方法从数据库中获取数据。大多数时候一切都很好。我最近遇到了一些 ObjectContextDisposed 异常,我很好奇为什么我的解决方案有效:
这是我抛出 ObjectContextDisposed
的原始代码:
public Task<List<string>> GetEventParameterMru(EventParameter parameter, int count = 20)
{
using (var repo = new ConfigurationRepository())
{
return repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count)
}
}
这是我不会抛出的新代码:
public async Task<List<string>> GetEventParameterMru(EventParameter parameter, int count = 20)
{
using (var repo = new ConfigurationRepository())
{
var result = await repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count);
return result;
}
}
有人可以向我解释一下区别是什么,以及它为什么有效吗?
仅供引用,在我对这个方法的所有使用中,我调用了 await GetEventParameterMru()
谢谢
最佳答案
GetEventParameterMRU
显然是一种启动 Task
以检索某些数据的方法。因此 GetEventParameterMRU
在 repo
上的所有操作完成之前返回。
您的代码的两个版本都使用 using
语句,该语句被转换为 try/finally
block 。在 finally
block 中,repo
将被处理。
在您的第一个版本中,您在调用 GetEventParameterMRU
(开始任务)后立即返回。这意味着当使用 repo
的 Task
仍在运行时,立即处理 repo
。因此,当此 Task
访问 repo
时,您会收到您的
ObjectDisposedException
在第二个版本中,您使用 await
。因此,编译器将您的整个方法翻译成一个状态机。该方法在 await
语句处将控制权返回给其调用者,但没有传递 finally
block 。
当 Task
完成时,您的方法将在 await
语句之后继续执行。
因此 repo
仅在 Task
完成时被释放。所以您不会得到 ObjectDisposedException
。
关于c# - 这两个异步实现之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37583237/