说我有以下代码段:
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不是“线程安全的”。所以我有点困惑:
async/await
用于与dbContext相关的调用.ConfigureAwait(false)
。我已经读到这告诉我们不要重新进入MVC和WebApi控制器所需的“.NET上下文” - 但这是为这些控制器提供服务的应用程序的服务层。我还读到使用它可以防止死锁。dbContext
Task.WhenAll()
实例并行化调用
醇>
以下代码段是否是正确方向的可扩展,线程安全的步骤?
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;
}
答案 0 :(得分:3)
简短回答是"是","是","是"。
很长的答案是虽然db上下文不是线程安全的,但async
/ await
构造仍然没有将db上下文传递给其他线程,所以你在这里很安全。
就ConfigureAwait(false)
的调用而言,除了UI代码之外,你应该在任何地方都这样做。由于数据库代码很少放在UI层中(它永远不会放在UI级别的高质量生产代码中),因此您应该在后端进行的每个异步调用中使用ConfigureAwait(false)
。
最后,如果通过调用db context的async
方法创建多个任务,则可以创建协同例程。它们并行化系统外的工作(例如,进行并发数据库调用),但最终它们并不是同时运行的。这样可以保护您的数据库上下文安全,因为对它的任何更改都是按顺序应用的。