我可以使用异步/等待与dbContext?如果是这样,我应该何时使用ConfigureAwait(false)

本文关键字:我应该 何时使 false ConfigureAwait 如果 异步 可以使 等待 我可以 dbContext | 更新日期: 2023-09-27 18:14:18

假设我有以下代码片段:

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

现在我正试图通过利用async/await来大规模地提高这个代码片段的性能,但是我读到dbContext不是"线程安全的"。所以我有点困惑:

  1. 我是否可以使用async/await与dbContext相关的调用
  2. 当我这样做时是否应该使用.ConfigureAwait(false)。我读到这告诉我们不要再进入"。这是MVC和WebApi控制器所需要的——但这是为这些控制器服务的应用程序的服务层。我也读到使用这个可以防止死锁。
  3. 无论是否-在更复杂的场景中-我可以通过使用Task.WhenAll()来并行调用dbContext的相同实例

下面的代码片段是一个可伸缩的、线程安全的、朝着正确方向迈出的一步吗?

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;
}

我可以使用异步/等待与dbContext?如果是这样,我应该何时使用ConfigureAwait(false)

简短的回答是"Yes", "Yes"answers"Yes"。

长答案是,虽然db上下文不是线程安全的,async/await结构不会传递db上下文给其他线程,所以你在这里是安全的。

对于ConfigureAwait(false)的调用,除了UI代码,您应该在所有地方都这样做。因为数据库代码很少放在UI层(在高质量的产品代码中,它从不放在UI层),你应该在后端进行的每个异步调用中使用ConfigureAwait(false)

最后,如果通过调用db上下文的async方法来执行多个任务,则创建协同例程。它们在你的系统外并行工作(例如并发DB调用),但在你的终端上它们不是并发运行的。这保证了db上下文的安全,因为对它的任何更改都是顺序应用的。