【问题标题】:Can I use Async/Await with dbContext? If so, when should I use ConfigureAwait(false)?我可以将 Async/Await 与 dbContext 一起使用吗?如果是这样,我应该什么时候使用 ConfigureAwait(false)?
【发布时间】:2016-10-23 00:18:56
【问题描述】:

假设我有以下sn-p:

using (var db = new dbContext()){
     var user = db.Users.Find(3);
     user.Name = "newName";
     var viewModel = GetViewModelAndDoStuffToUser(user);
     db.SaveChanges();
     return viewmodel;
}

现在我正在尝试通过利用 async/await 来大规模提高这个 sn-p 的性能,但我读到 dbContext 不是“线程安全的”。所以我有点困惑:

  1. 我是否可以在与 dbContext 相关的调用中使用 async/await
  2. 我是否应该使用.ConfigureAwait(false)。我读过这告诉我们不要重新输入 MVC 和 WebApi 控制器所需的“.NET 上下文”——但这是为这些控制器提供服务的应用程序的服务层。我还读到使用它可以防止死锁。
  3. 无论是否 - 在更复杂的场景中 - 我可以通过使用 Task.WhenAll() 来并行化使用 dbContext 的同一实例的调用

以下 sn-p 是否会是朝着正确方向迈出的可扩展、线程安全的一步?

using (var db = new dbContext()){
     var user = await db.Users.FindAsync(3).ConfigureAwait(false);
     user.Name = "newName";
     var viewModel = await GetViewModelAndDoStuffToUserAsync(user).ConfigureAwait(false);
     await db.SaveChangesAsync().ConfigureAwait(false);
     return viewmodel;
}

【问题讨论】:

    标签: c# .net multithreading entity-framework asynchronous


    【解决方案1】:

    简短的回答是“是”、“是”和“是”。

    长答案是,尽管 db 上下文不是线程安全的,async/await 构造无论如何都不会将 db 上下文传递给其他线程,所以你在这里是安全的。

    ConfigureAwait(false) 的调用而言,除了UI 代码之外,您应该在任何地方进行调用。由于数据库代码很少放在 UI 层(在高质量的生产代码中从不放在 UI 层),因此您应该在后端进行的每个异步调用中使用 ConfigureAwait(false)

    最后,如果您通过调用 db 上下文的 async 方法来执行多个任务,您将创建协同例程。它们在您的系统之外并行工作(例如,进行并发 DB 调用),但在您的端,它们不会同时运行。这可以确保您的数据库上下文安全,因为对其进行的任何更改都是按顺序应用的。

    【讨论】:

    • 谢谢你!我刚刚添加了第三种情况,以防您有时间解决它。
    • 而且 - WebApi Controller 是否构成“UI 代码”?或者这只是 MVC 控制器/动作?
    • @SB2055 WebApi Controller 不需要ConfigureAwait(true),只有桌面 UI 需要。
    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 2019-04-12
    • 2015-04-30
    • 1970-01-01
    • 2014-01-19
    • 2015-06-24
    • 2018-08-04
    相关资源
    最近更新 更多