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

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

Department department = await db.Departments.FindAsync(id); 

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

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

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

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

异步:

  • 几乎从不用异步消耗线程池(情况必须是极端的)
  • 几乎任意级别的并发(并发请求和操作)
  • 每个线程保存可节省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使用情况(异步很棒)。 或者,他们没有意识到异步数据库调用几乎总是浪费开发人员的时间而没有任何好处。 大多数人都没有意识到这一点,因为async是现在的发展方式。

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

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

理想情况下,涉及等待一段时间的任何事情都应该异步完成。 数据库查询通常必须调用远程服务器,发送查询,然后等待服务器响应结果。 这使得它成为异步的主要候选者,因为整个“等待服务器响应”部分是您在应用程序中无法解释的变量。

使用async允许Web服务器在代码等待异步操作完成时重用当前线程来记录其他Web请求。 完成后,会将一个线程返回给您的应用程序以继续处理。 如果您运行同步,那么当您在等待数据库或任何其他长时间运行的进程时,该线程将死锁并且不可用于Web服务器池。 如果执行此操作,Web服务器可能会耗尽可用线程,并且必须开始排队进一步请求。 Async通过释放线程来解决这个问题,因为它们只是在等待某些东西,增加了Web服务器可以处理的潜在负载。