不等待SaveChangesAsync()是否安全?

时间:2019-02-26 17:26:41

标签: c# entity-framework asp.net-core async-await

请考虑以下WebAPI方法:

[HttpPost]        
public async Task<IHttpResult> CreateWorkItem(Item wi)
{
    var item = await dataContext.Item.AddAsync(wi);
    await dataContext.SaveChangesAsync();
    return Ok();
}

是否存在不使用await方法的SaveChangesAsync()安全的情况?

理论上,如果我只是在后台完成对数据库的刷新时发送响应,则响应时间会更快。

我的假设正确吗?

1 个答案:

答案 0 :(得分:6)

await关键字没有什么神奇之处。从字面上看,它的意思是“等待此任务完成再继续”。任务热返回或已经开始执行,因此无论您是否等待任务,工作都在进行中。

但是,在您不等待任务完成的情况下,事情会变得很混乱。特别是在这里,您的上下文(实际上执行保存操作所需的上下文)(请记住它拥有物理数据库连接)是请求范围的。这意味着,如果您不等待保存并从操作中返回,则现在实际上是在争夺哪个完成了第一个操作:保存操作或请求结束。如果首先发生请求结束(即将最终响应刷新到客户端),则会使用活动事务和您的SQL连接来处理上下文。

等待的另一个重要原因是正确的异常处理。如果不等待,保存期间抛出的任何异常都会被吞噬,因为代码已经继续运行。这意味着您无法真正保证保存成功完成。您所拥有的只是一个愿望和祈祷。

除了非常罕见例外,所有异步任务都应一直等待。它不一定总是在同一行中(例如,当使用诸如Task.WhenAll之类的东西来等待一系列任务时),但是在某个时刻或另一个地方,应该有await关键字。 FWIW,那些罕见的例外大多限于台式机和移动开发,在这些情况下,您经常需要在新线程上进行工作以防止阻塞主线程或UI线程。对于Web应用程序而言,这并不是遥不可及的问题,因此您可以考虑在这种情况下普遍使用“等待所有事物”规则。