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

时间:2014-08-01 18:55:48

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

最新的EF教程介绍了如何将EF 6与MVC 5结合使用,似乎倾向于使用asych调用数据库,如:

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

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

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

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

3 个答案:

答案 0 :(得分:35)

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

<强>异步:

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

同步

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

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

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

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

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

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

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

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

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

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

答案 1 :(得分:12)

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

使用async允许ASP.NET最大限度地利用线程池,从而带来非常重要的可伸缩性优势。

答案 2 :(得分:4)

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

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