为什么EF 6教程使用异步调用?

pub*_*tic 17 c# asp.net-mvc entity-framework async-await

关于如何将EF 6与MVC 5一起使用的最新EF教程似乎倾向于使用对数据库的asych调用,如:

Department department = await db.Departments.FindAsync(id);
Run Code Online (Sandbox Code Playgroud)

这是新标准/最佳做法吗?

我不确定ASP.NET MVC的这种开发风格有什么好处.

有人可以评论这种模式,这是MS推广的新标准吗?

usr*_*usr 38

为了决定是进行异步还是同步,请比较好处和成本:

异步:

  • 几乎从不用异步消耗线程池(情况必须是极端的)
  • 几乎任意级别的并发(并发请求和操作)
  • 每个线程保存可节省1MB内存
  • 安全的内部请求并发感谢 SynchronizationContext
  • 由于减少了OS调度开销,可以通过高负载情况下的低两位数百分比来增加吞吐量.也就是说,几乎没有生产应用程序在高CPU负载下,因为如果它接近不可用(如果负载高峰,应用程序开始丢弃请求)

同步:

  • 更简单的代码:await使99%的情况(几乎)像同步代码一样简单.也就是说,Stack Overflow上每天发出的10多个异步问题讲的是另一种语言.当您偏离简单路径时会出现边缘情况.此外,在使用旧版库时,例如,要求您提供同步回调
  • 减少编码和调试工作量
  • Profiler-friendly(您可以分析应用程序或暂停调试器,看看应用程序现在正在做什么.不能使用异步.)
  • 与遗留代码和库完美互操作

如果要调用高延迟服务,请选择与ASP.NET的异步.Web服务可能是高延迟.OLTP数据库几乎总是低延迟.

如果您的应用程序受益于非常高的并发性(100+),请选择async.大多数应用程序没有如此高的级别,或者它们的后端服务不会承受如此大的负载.没有必要使Web应用程序扩展,但后端过载.调用链中的所有系统都必须受益于高度并发性才能使异步变得有益.

典型的高延迟服务(异步的好例子):

  • 网页服务
  • 等待(例如睡觉)
  • 节流(SemaphoreSlim,...)
  • 一些云服务(Azure)
  • 长时间运行的数据库查询(例如报告或ETL)

典型的低延迟服务(同步的好例子):

  • 数据库调用:大多数OLTP查询都是低延迟的,因为您可以假设数据库服务器不会过载.向它投掷100个并发查询没有意义.不会让它们更快完成.
  • 文件系统:与数据库相同.

这些按典型案例分类.所有这些也可以属于相反的类别.

您可以在同一个应用中混合同步和异步.当它处于最佳位置时使用异步.

那么为什么Microsoft和Entity Framework团队会推广异步使用?这是答案的主观部分:它可能是微软的内部政策.他们可能会预测客户端应用程序中的EF使用情况(异步很棒).或者,他们没有意识到异步数据库调用几乎总是浪费开发人员的时间而没有任何好处.大多数人都没有意识到这一点,因为异步是这些日子的方式.

  • @valid_where_void:使用EF工作模式与async vs sync无关.更多的是EF的新版本以及对模式和流程的新理解和建议.使用EF的工作单元/存储库*从来都不是一个好主意,教程最终会被更新以反映出来. (2认同)
  • @usr:两件事:1)说“从不”排气线程池是不准确的。即使您异步执行所有操作,您仍然可以耗尽线程池。它只是给您比同步更高的上限。2)也许.NET 4.5之前的同步可以使“更简单的代码”成为现实,但是使用async / await进行异步几乎是非常愚蠢的,并且根本没有使代码复杂化。 (2认同)

Ste*_*ary 13

在ASP.NET上,您应该使用异步API来处理与I/O相关的任何事情,包括数据库访问和Web服务调用.

使用async允许ASP.NET最大限度地利用线程池,从而产生非平凡的可伸缩性优势.

  • 正如Stephen提到的@usr,缩放是在线程池中.即使您的网站的所有页面都不依赖于数据库,使用异步调用也会释放线程来处理请求.扩展的好处绝对是非平凡的.如果你想支持成千上万的请求,当然你需要查看你的数据库,但这并不是他在这种情况下的意思. (5认同)
  • @usr:现代异步几乎和同步一样容易。甚至在线程池用尽之前,它的确带来了好处:特别是,由于注入速率有限,`async`的扩展速度比线程池本身快。因此,这对于突发流量非常有用。 (2认同)
  • @usr:您正在[针对ASP.NET上异步DB调用的经典案例](http://blogs.msdn.com/b/rickandy/archive/2009/11/14/should-my-database-calls -be-asynchronous.aspx)。当异步比较困难并且只有一个SQL Server后端时,这种说法很有意义。如今,异步很容易,并且后端通常比Azure SQL或可伸缩NoSQL多,而且这种说法也不太成立。(这仍然是一个有效的论点;如今,它的作用已经减弱了很多)。 (2认同)