请考虑以下WebAPI方法:
[HttpPost]
public async Task<IHttpResult> CreateWorkItem(Item wi)
{
var item = await dataContext.Item.AddAsync(wi);
await dataContext.SaveChangesAsync();
return Ok();
}
是否存在不使用await
方法的SaveChangesAsync()
安全的情况?
理论上,如果我只是在后台完成对数据库的刷新时发送响应,则响应时间会更快。
我的假设正确吗?
答案 0 :(得分:6)
await
关键字没有什么神奇之处。从字面上看,它的意思是“等待此任务完成再继续”。任务热返回或已经开始执行,因此无论您是否等待任务,工作都在进行中。
但是,在您不等待任务完成的情况下,事情会变得很混乱。特别是在这里,您的上下文(实际上执行保存操作所需的上下文)(请记住它拥有物理数据库连接)是请求范围的。这意味着,如果您不等待保存并从操作中返回,则现在实际上是在争夺哪个完成了第一个操作:保存操作或请求结束。如果首先发生请求结束(即将最终响应刷新到客户端),则会使用活动事务和您的SQL连接来处理上下文。
等待的另一个重要原因是正确的异常处理。如果不等待,保存期间抛出的任何异常都会被吞噬,因为代码已经继续运行。这意味着您无法真正保证保存成功完成。您所拥有的只是一个愿望和祈祷。
除了非常罕见例外,所有异步任务都应一直等待。它不一定总是在同一行中(例如,当使用诸如Task.WhenAll
之类的东西来等待一系列任务时),但是在某个时刻或另一个地方,应该有await关键字。 FWIW,那些罕见的例外大多限于台式机和移动开发,在这些情况下,您经常需要在新线程上进行工作以防止阻塞主线程或UI线程。对于Web应用程序而言,这并不是遥不可及的问题,因此您可以考虑在这种情况下普遍使用“等待所有事物”规则。