你可以找到我的MSDN article on the subject helpful;我在那篇文章中花了很多篇幅描述何时应该在 ASP.NET 上使用async,而不仅仅是如何在 ASP.NET 上使用async。
我对在 ASP.NET MVC 中使用异步操作有一些顾虑。什么时候可以提高我的应用程序的性能,什么时候不可以。
首先,了解async/await 的全部意义在于释放线程。在 GUI 应用程序上,主要是关于释放 GUI 线程,以便用户体验更好。在服务器应用程序(包括 ASP.NET MVC)上,主要是关于释放请求线程,以便服务器可以扩展。
特别是,它不会:
- 让您的个人请求更快地完成。事实上,它们会慢一些(只是一点点)。
- 点击
await 时返回调用者/浏览器。 await 只“屈服”于 ASP.NET 线程池,而不是浏览器。
第一个问题是 - 在 ASP.NET MVC 中随处使用异步操作是否很好?
我会说在您进行 I/O 的任何地方都可以使用它。不过,它不一定是有益的(见下文)。
但是,将它用于受 CPU 限制的方法是不好的。有时开发人员认为他们可以通过在他们的控制器中调用Task.Run 来获得async 的好处,这是一个可怕的想法。因为该代码最终通过占用另一个线程来释放请求线程,所以根本没有任何好处(事实上,他们正在承担额外线程切换的代价)!
当我想查询数据库(通过 EF/NHibernate/其他 ORM)时,我应该使用 async/await 关键字吗?
您可以使用任何可用的等待方法。目前大多数主要玩家都支持async,但也有一些不支持。如果您的 ORM 不支持 async,则不要尝试将其包装在 Task.Run 或类似的东西中(见上文)。
请注意,我说的是“您可以使用”。如果您正在谈论具有单个数据库后端的 ASP.NET MVC,那么您(几乎可以肯定)不会从 async 获得任何可扩展性优势。这是因为 IIS 可以处理比单个 SQL 服务器(或其他经典 RDBMS)实例更多的并发请求。但是,如果您的后端更现代 - SQL 服务器集群、Azure SQL、NoSQL 等 - 并且您的后端可以扩展,并且您的可扩展性瓶颈是 IIS,那么您可以从 @ 获得可扩展性优势987654335@.
第三个问题——ONE single action 方法中可以使用 await 关键字异步查询数据库多少次?
只要你喜欢。但是,请注意,许多 ORM 具有每个连接一个操作的规则。特别是,EF 只允许每个 DbContext 进行单个操作;无论操作是同步的还是异步的,都是如此。
另外,请再次记住后端的可扩展性。如果您使用的是 SQL Server 的单个实例,并且您的 IIS 已经能够使 SQLServer 保持满负荷运行,那么对 SQLServer 施加双倍或三倍的压力对您毫无帮助。