在操作方法中使用await-async是否有任何实际好处?

10 浏览
0 Comments

在操作方法中使用await-async是否有任何实际好处?

我对在ASP.NET MVC中使用异步操作有一些担忧。什么情况下它能提升我的应用性能,什么情况下又不能?\n

    \n

  1. 在ASP.NET MVC中到处使用异步操作是否好?
  2. \n

  3. 关于可等待的方法:当我想要通过EF/NHibernate/其他ORM查询数据库时,我应该使用async/await关键字吗?
  4. \n

  5. 在一个单一的操作方法中,我可以使用多少次await关键字来异步查询数据库?
  6. \n

0
0 Comments

在ASP.NET MVC中,到底是否应该在所有的action中都使用async呢?就像在编程中一样,这取决于具体情况。在选择使用async-await时,需要权衡各方面的利弊。async-await在你预计服务会同时收到多个请求,并且你希望能够良好地进行扩展时,会发挥其优势。async-await在什么地方对扩展性有帮助呢?当你调用异步IO操作(例如网络调用或者访问数据库)时,在同步调用的情况下,当前线程会被阻塞,等待请求完成。而使用async-await则可以使框架为你创建一个状态机,确保在IO调用完成后,方法能够从离开的地方继续执行。

需要注意的是,这个状态机会带来一些微妙的开销。将方法设置为异步并不会使其执行速度更快,这是一个需要理解的重要因素,也是很多人存在的误解。

另一个需要考虑的问题是,使用async-await会使代码“异步化”,这意味着你会在整个调用栈中看到async的影响,从顶层到底层。这意味着如果你想要暴露同步的API,你经常会发现自己需要复制一定量的代码,因为async和sync并不很好地兼容。

如果你选择使用异步IO调用,那么在查询数据库时使用async-await是一个很好的选择,因为越来越多的现代数据库提供者都会暴露实现TAP(Task Asynchronous Pattern)的异步方法。

在一个单独的action方法中,你可以使用任意多次的await关键字来异步查询数据库,只要你遵循数据库提供者规定的规则。你可以进行任意数量的异步调用。如果你有独立于彼此并且可以并发进行的查询,你可以为每个查询启动一个新的任务,并使用await Task.WhenAll来等待它们都完成。

异步的数据库调用并不会使执行速度更快,但它允许同一个IIS机器处理更多的请求,因为线程池线程不会被浪费。它还降低了CPU成本,因为阻塞调用实际上会在真正阻塞之前进行CPU密集型自旋等待。在高负载情况下,这可能是机器是否能够应对或者失败并重启的关键。我知道,我的说法是否清楚?

你的回答没有提到IIS的具体情况 - 在整个过程中使用异步的主要原因是防止IIS崩溃/重启。对于没有经历过这种情况的人来说,他们可能不会理解“扩展性好”的意思是“你的服务器在负载下不会崩溃”。或者这可能是一种“一次被烧过......”的情况。

0
0 Comments

使用await-async在操作方法中有实际好处吗?

随着互联网应用程序的发展,处理并发请求的能力变得越来越重要。在传统的同步编程模型中,一个请求会占用一个线程,当线程被阻塞时,即使没有其他任务需要处理,它也无法被重新分配给其他请求。这会导致服务器资源的浪费,同时也会降低系统的吞吐量和响应时间。

为了解决这个问题,引入了异步编程模型,在服务器端处理请求时可以释放线程,使其可以处理其他请求。而使用await-async关键字可以方便地实现异步编程模式。

但是,在操作方法中使用await-async是否有实际好处?这取决于具体的情况。如果一个操作方法需要执行多个独立的长时间运行的操作,并且这些操作是相互独立的,那么使用await-async可以提高系统的吞吐量和响应时间。通过释放线程,可以将更多的并发请求分配给服务器,从而提高系统的性能。

然而,如果数据库是系统的瓶颈,使用await-async并不能加快数据库的响应速度。数据库服务器通常无法处理和IIS线程池一样多的并发请求。此时,使用await-async只会增加数据库的负担,而不能提高系统的性能。

需要注意的是,使用await-async并不意味着并行执行。异步执行只是将一个有价值的线程从阻塞状态中释放出来,以便处理其他请求,而不会增加系统的复杂性和性能开销。这意味着同一台IIS服务器可以处理更多的并发请求,但并不意味着请求的处理速度会更快。

因此,是否在操作方法中使用await-async取决于具体的情况。如果操作方法需要执行多个独立的长时间运行的操作,并且数据库不是系统的瓶颈,那么使用await-async可以提高系统的性能。但如果数据库是系统的瓶颈,使用await-async并不能提高系统的性能,反而会增加数据库的负担。

,使用await-async可以提高系统的吞吐量和响应时间,但需要根据具体情况来决定是否使用。在设计和实现系统时,需要考虑到数据库的性能和并发请求的处理能力,以确定是否使用await-async。

0
0 Comments

使用await-async在action方法中有什么实际好处吗?

这个问题的出现原因是有人对在ASP.NET MVC中使用异步操作有一些疑虑,想知道它是如何提高应用程序性能的以及何时使用它。

解决方法是首先要理解async/await的目的是为了释放线程。在GUI应用程序中,它主要是为了释放GUI线程,以提高用户体验。在服务器应用程序(包括ASP.NET MVC)中,它主要是为了释放请求线程,以便服务器可以扩展。

具体来说,它不会有以下好处:

- 加快单个请求的完成速度,事实上,它们的完成速度会稍微慢一些。

- 当你遇到一个await时,不会立即返回给调用者/浏览器。await只是“让出”给ASP.NET线程池,而不是浏览器。

回答第一个问题,是否在ASP.NET MVC中的每个地方都使用async操作是好的?

回答是在进行I/O操作的地方都可以使用,但并不一定有好处。然而,对于CPU绑定的方法来说使用它是不好的。有时开发人员认为通过在控制器中调用Task.Run来获得async的好处,这是一个糟糕的想法。因为这段代码会通过占用另一个线程来释放请求线程,所以根本没有好处(事实上,它们会增加额外的线程切换的开销)。

回答第二个问题,当我想要通过EF/NHibernate/其他ORM查询数据库时,是否应该使用async/await关键字?

你可以使用任何可等待的方法,目前大多数主要的ORM都支持async,但也有一些不支持的。如果你的ORM不支持async,那么不要试图用Task.Run等方式来包装它。

注意我说的是"你可以使用"。如果你是在谈论带有单个数据库后端的ASP.NET MVC,那么你几乎肯定不会从async中获得任何可扩展性的好处。这是因为IIS可以处理比单个SQL服务器实例更多的并发请求。然而,如果你的后端更现代化 - SQL服务器集群、Azure SQL、NoSQL等,并且你的后端可以扩展,并且你的可扩展性瓶颈是IIS,那么你可以从async中获得可扩展性的好处。

回答第三个问题,一个单一的action方法中可以使用多少次await关键字来异步查询数据库?

可以使用任意多次。然而,许多ORM有一个每个连接一次操作的规则。特别是,EF只允许每个DbContext执行一次操作,无论操作是同步还是异步的。

此外,再次考虑你的后端的可扩展性。如果你正在连接一个单个的SQL Server实例,并且你的IIS已经能够保持SQLServer满负荷运行,那么增加对SQLServer的压力不会对你有任何帮助。

关于单个数据库实例的情况,释放一个线程对于CPU绑定的操作有好处吗?

不,因为你不会真正地“释放一个线程”,而是会跳转线程。你不能用一个CPU绑定的操作来释放一个线程,因为它需要一个线程来运行。你可以通过使用另一个线程来释放请求线程,但这只会导致额外的线程切换,并可能扰乱ASP.NET线程池的平衡启发式算法。

很有趣。那么I/O“释放”线程对于CPU绑定的操作不可用吗?

当进行(正确的异步)I/O操作时,不会使用线程。我有一篇博文详细介绍了这个问题。

如果IIS线程池>DB连接池,会导致死锁吗?

不,我不认为会导致死锁。

允许多个结果集的设置是否可以克服EntityFramework默认的每个上下文限制1个操作的限制?

我不知道。

IIS和单个SQL Server实例可以处理多少请求?我该如何找到这些数字?

这取决于配置和硬件。找到这些数字的唯一方法是在你自己的服务器上进行负载测试。

对不起,这个愚蠢的问题是什么意思,"CPU绑定的方法"是什么意思?

指的是完全在CPU上执行的方法。也就是说,它们不进行I/O或阻塞。

我有一个Web API接口点。如果同时有1000个请求同时访问这个接口点,我的代码会负责处理这1000个请求,比如将这个接口点设置为“fire and forget”,还是这取决于服务器和IIS的能力?

抱歉,我不理解这个问题,但它似乎不是对这个问题/答案的澄清。请在SO上提一个单独的问题。

很抱歉,先生,但是SO不接受我试图理解的这两行问题。当我在研究这个问题时,例如,如果我有一个Web API接口点,同时被1000个用户调用,那么这个接口点能够处理这1000个请求吗,还是我应该将它设置为异步来处理1000个请求?

0