等待任务会让 HTTP 请求变慢吗?

问题描述 投票:0回答:1

在 ASP.NET Core 控制器中,我们需要从数据库中获取一些数据。使用 EF Core 我们必须选择:

ToList()
ToListAsync()
。这是我对两者之间差异的理解,我想知道我是否正确:

  • HTTP 请求到达我们的服务器 (Kestrel)
  • 线程将根据请求执行管道
  • 在某个时刻它到达我们的控制器,如果我们使用
    ToList()
    ,线程必须等待,直到从数据库获取数据。根据我们的数据库服务器所在的位置,这可能非常快(在同一台机器上)或非常慢(在地球的另一边),但如果我们使用
    ToListAsync()
    ,线程将被释放,并且有机会拾取另一个线程HTTP 请求,因此,当我们为请求 A 获取数据时,释放的线程可能会完成请求 B。
    这是我们应该使用异步版本的主要原因。这里需要注意的重要一点是,请求 A 不会执行得更快,它实际上执行得有点慢,因为框架会进行上下文切换。因此,(如果我是对的)我们有机会处理更多请求,但每个请求处理速度会慢一些。

所以,我的问题是,如果我们知道获取速度非常快(同一台机器或同一数据中心)并且我们知道发送请求的用户不多(例如:拥有 15-20 个用户的管理面板网站),那么使用它实际上是否更好同步版本并避免上下文切换?

asp.net-core .net-core async-await concurrency .net-8.0
1个回答
0
投票

简而言之,您的理解可以说是正确的。正如值得一读的 .NET 中的异步编程 - 简介、误解和问题 文章中所述:

误解#2:异步/等待让你的代码运行“更快”

使用

async
/
await
并不是为了让代码“运行得更快”,它会比类似的同步方法运行得更慢(并使用更多内存)。相反,使用
async / await
可以获得效率(或者在 UI 应用程序的情况下,卸载)。我想当并行运行事物与一般运行速度更快的代码混为一谈时,就会出现这种误解。

来自 Stephen Toub 的 异步编程 - 异步性能:了解异步和等待的成本

异步方法是一种强大的生产力工具,使您能够更轻松地编写可扩展且响应灵敏的库和应用程序。但请务必记住,异步性并不是针对单个操作的性能优化。采用同步操作并将其设为异步操作必然会降低该操作的性能,因为它仍然需要完成同步操作所做的所有事情,但现在需要额外的约束和注意事项。那么,您关心异步性的一个原因是总体性能:当您异步编写所有内容时,整个系统的性能如何,这样您就可以重叠 I/O,并通过仅在实际需要时消耗宝贵的资源来实现更好的系统利用率执行。

至于你的问题:

直到从数据库中获取数据 所以,我的问题是我们是否知道获取速度非常快(同一台机器或同一数据中心)

这里有几个潜在的警告:

  1. 数据库位置并不是响应时间潜在延迟的唯一来源,您的查询可能“繁重”或涉及一些事务,或者您的数据库可能由于某些原因而过载,导致请求占用“显着”的时间时间
  2. 虽然同一台机器可以“接近”到足以在使用异步处理时产生显着影响(实际上,我已经在一个应用程序中看到了 CPU 消耗的显着影响,该应用程序切换到通过 TCP/IP 进行异步工作,但这是一种非常罕见的情况),对于数据中心来说情况可能并非如此。

我们知道发送请求的用户并不多(例如:拥有 15-20 个用户的管理面板网站)使用同步版本并避免上下文切换实际上更好吗?

可以说,如果您的 RPS 较低,那么一般来说您不应该在意,影响应该几乎不明显。当然,与所有与性能相关的问题一样,您需要彻底测试您的实际设置(实际硬件、软件和使用/负载模式),但在这种具体情况下,听起来不值得花费时间(除非您非常非常感兴趣)任务并想尝试一些工具/方法/等科学)。

© www.soinside.com 2019 - 2024. All rights reserved.