C# 不等待saveChangesSync()是否安全?

C# 不等待saveChangesSync()是否安全?,c#,entity-framework,asp.net-core,async-await,C#,Entity Framework,Asp.net Core,Async Await,考虑以下WebAPI方法: 是否存在不等待SaveChangesSync方法的安全情况 理论上,如果在后台完成对数据库的刷新时发送响应,则响应时间会更快 我的假设正确吗?等待关键字没有什么神奇之处。它的字面意思是等待这项任务完成后再继续。任务返回热,或者已经开始,所以无论您是否等待它们,工作都在进行中 然而,在不等待任务完成的情况下,事情会变得很危险。特别是,在这里,实际执行保存操作所需的上下文记住,它拥有物理DB连接是请求范围的。这意味着,如果您不等待保存并从操作返回,那么您现在基本上处于一

考虑以下WebAPI方法:


是否存在不等待SaveChangesSync方法的安全情况

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


我的假设正确吗?

等待关键字没有什么神奇之处。它的字面意思是等待这项任务完成后再继续。任务返回热,或者已经开始,所以无论您是否等待它们,工作都在进行中

然而,在不等待任务完成的情况下,事情会变得很危险。特别是,在这里,实际执行保存操作所需的上下文记住,它拥有物理DB连接是请求范围的。这意味着,如果您不等待保存并从操作返回,那么您现在基本上处于一场竞赛中,要看哪一个完成了第一个:保存操作还是请求的结束。如果首先出现请求的结束,即刷新到客户端的最终响应,则上下文将被释放,并使用活动事务及其SQL连接

等待的另一个重要原因是正确的异常处理。如果不等待,则在保存过程中抛出的任何异常都将基本上被吞没,因为代码已经继续。这意味着您无法真正保证保存实际上已成功完成;你所拥有的只是一个愿望和祈祷


除了极少数例外,所有异步任务都应该一直等待。它并不总是需要在同一行中,例如在使用Task.whell之类的东西时,它需要等待一系列任务,但在某个时刻,wait关键字应该在那里。FWIW,这些罕见的例外大多局限于桌面和移动开发,在这些开发中,您经常需要启动新线程以防止阻塞主线程或UI线程。对于Web应用程序来说,这并不是一个遥远的问题,所以你可以考虑在这个上下文中等待所有事物规则。

< P> >等待关键字没有什么神奇之处。它的字面意思是等待这项任务完成后再继续。任务返回热,或者已经开始,所以无论您是否等待它们,工作都在进行中

然而,在不等待任务完成的情况下,事情会变得很危险。特别是,在这里,实际执行保存操作所需的上下文记住,它拥有物理DB连接是请求范围的。这意味着,如果您不等待保存并从操作返回,那么您现在基本上处于一场竞赛中,要看哪一个完成了第一个:保存操作还是请求的结束。如果首先出现请求的结束,即刷新到客户端的最终响应,则上下文将被释放,并使用活动事务及其SQL连接

等待的另一个重要原因是正确的异常处理。如果不等待,则在保存过程中抛出的任何异常都将基本上被吞没,因为代码已经继续。这意味着您无法真正保证保存实际上已成功完成;你所拥有的只是一个愿望和祈祷


除了极少数例外,所有异步任务都应该一直等待。它并不总是需要在同一行中,例如在使用Task.whell之类的东西时,它需要等待一系列任务,但在某个时刻,wait关键字应该在那里。FWIW,这些罕见的例外大多局限于桌面和移动开发,在这些开发中,您经常需要启动新线程以防止阻塞主线程或UI线程。对于Web应用程序来说,这并不是一个遥远的问题,因此您可以考虑在这一上下文中等待所有规则的通用性。没有,没有。你会有更快的响应时间,因为上下文会被释放,没有任何东西会被保存。你是说线程会释放并取消savechangessync,即使没有完成它?它不是要异步继续吗?不,不是。没有人知道您创建了该私有任务,因此将不让任何人来确保它能够成功完成。在这种情况下,不等待saveChangesSync方法是安全的吗?=>没有,没有。你会有更快的响应时间,因为上下文会被释放,没有任何东西会被保存。你是说线程会释放并取消savechangessync,即使没有完成它?它不是要异步继续吗?不,不是。没有人知道您创建了该私有任务,因此确保它能够成功完成将不由任何人负责。如果正在完成的工作受CPU限制,您通常不需要新线程吗?您仍然可以在WinForms中等待I/O,而无需生成新线程。我想你不必一直等待的原因
在WinForms中,是由于事件循环。不知道手机是怎么工作的,不一定。在新线程上运行I/O绑定的工作是很常见的,因为仅异步并不能保证不占用UI线程。异步允许线程切换,但不能保证线程切换,因此,虽然异步对于CPU绑定的工作可能更重要,因为异步甚至不是一个选项,但有时使用异步I/O工作启动新线程仍然很重要,这取决于所做的工作。也许我遗漏了一些东西,但I/O绑定异步依赖于I/O完成端口,它们不是线程。那么,这将如何绑定UI线程呢?我所熟悉的唯一一个不属于这种情况的实例是,您有一个伪异步,例如Oracle的库,在同步代码上有一个异步包装器。这并不是说线程一定会被绑定,而是它也可能不会被释放。对于某些操作来说,这可能不是什么大问题,但在某些情况下可能会导致UI暂停。同样,没有CPU绑定的工作那么重要,但是你不能说这是异步的,所以我将在UI线程上运行。如果正在完成的工作是CPU绑定的,你不通常只需要新线程吗?您仍然可以在WinForms中等待I/O,而无需生成新线程。我认为您不必在WinForms中一直等待的原因在于事件循环。不知道手机是怎么工作的,不一定。在新线程上运行I/O绑定的工作是很常见的,因为仅异步并不能保证不占用UI线程。异步允许线程切换,但不能保证线程切换,因此,虽然异步对于CPU绑定的工作可能更重要,因为异步甚至不是一个选项,但有时使用异步I/O工作启动新线程仍然很重要,这取决于所做的工作。也许我遗漏了一些东西,但I/O绑定异步依赖于I/O完成端口,它们不是线程。那么,这将如何绑定UI线程呢?我所熟悉的唯一一个不属于这种情况的实例是,您有一个伪异步,例如Oracle的库,在同步代码上有一个异步包装器。这并不是说线程一定会被绑定,而是它也可能不会被释放。对于某些操作来说,这可能不是什么大问题,但在某些情况下可能会导致UI暂停。同样,没有CPU绑定的工作那么重要,但不能笼统地说这是异步的,所以我将在UI线程上运行。
[HttpPost]        
public async Task<IHttpResult> CreateWorkItem(Item wi)
{
    var item = await dataContext.Item.AddAsync(wi);
    await dataContext.SaveChangesAsync();
    return Ok();
}