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

标签 c# asynchronous async-await task-parallel-library

我正在使用 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 以检索某些数据的方法。因此 GetEventParameterMRUrepo 上的所有操作完成之前返回。

您的代码的两个版本都使用 using 语句,该语句被转换为 try/finally block 。在 finally block 中,repo 将被处理

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

ObjectDisposedException


在第二个版本中,您使用 await。因此,编译器将您的整个方法翻译成一个状态机。该方法在 await 语句处将控制权返回给其调用者,但没有传递 finally block 。
Task 完成时,您的方法将在 await 语句之后继续执行。
因此 repo 仅在 Task 完成时被释放。所以您不会得到 ObjectDisposedException

关于c# - 这两个异步实现之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37583237/

相关文章:

node.js - 无服务器异步函数错误

c# - 如何在 C# 中获取唯一/不同的打印机型号名称?

c# - 带有可选参数的 .net MVC 操作

python - 一个干净、轻量级的 Python 扭曲替代品?

javascript - 如果我立即屈服,为什么我的 fork 会阻塞?

javascript - firebase 回调中无法识别异步函数

c# - Windows RT - StorageFile 的同步使用

c# - 如何在 XAML C# 的动态组合框中仅显示字典的值部分?

c# - ASP.NET ControllerBase 扩展方法在 Razor View 上不起作用

wpf - 我应该在UI Thread或Task.Run上使用async等待来处理多个文件吗?