这两个异步实现之间的区别

Sim*_*mon 2 c# asynchronous task-parallel-library async-await

我正在使用EF的异步方法从数据库中获取数据.大部分时间都很好.我最近遇到了一些ObjectContextDisposed异常,我很好奇为什么我的解决方案有效:

这是我的原始代码ObjectContextDisposed:

public Task<List<string>> GetEventParameterMru(EventParameter parameter, int count = 20)
{
    using (var repo = new ConfigurationRepository())
    {
        return repo.GetEventParameterMRU(_CurrentWorkpack, parameter, count)             
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的新代码,不抛出:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释有什么不同,为什么它有效?

仅供参考,在我使用这种方法的所有用法中,我打电话 await GetEventParameterMru()

谢谢

Ren*_*ogt 5

GetEventParameterMRU显然是一种开始Task检索一些数据的方法.所以GetEventParameterMRU在完成所有操作之前返回repo.

两个版本的代码都使用一个using语句,该语句被转换为一个try/finally块.在finally街区,repo将被处置.

在您的第一个版本中,您在调用(启动任务)后立即返回GetEventParameterMRU.这意味着repoTask使用repo仍在运行时立即处理.因此,当您Task访问时,repo您会收到您的

的ObjectDisposedException


在您使用的第二个版本中await.因此,编译器将您的整个方法转换为状态机.该方法在await语句处将控制权返回给其调用者,但传递该finally块.
Task完成时,你的方法的执行后继续await发言.
所以repo时候只能布置Task已经完成.所以你没有得到ObjectDisposedException.