.Net Core Web API 异步无关紧要?



我一直在用async关键字编写我的Web API控制器方法,并且一直在使用async。最近,我尝试制作一种方法同步,以查看它将如何影响性能,并震惊地发现它对任何其他HTTP请求没有阻碍影响。

举例 -

[Route("Foo")]
class FooController {
  [HttpGet("Hello")]
  public string GetHello()
  {
    Thread.Sleep(100000); // 100 seconds
    return "Hello";
  }
  [HttpGet("Goodbye")]
  public string GetGoodbye()
  {
    return "Goodbye";
  }
}

这样,我可以运行 GET => /Foo/Hello,然后是任意数量的 GET => /Foo/Goodbye,并且我的请求对Goodbye端点没有任何阻止。

我最初以为我是需要做出Hello方法async,以便向Goodbye Endpoint的请求毫不延迟返回。但是使此方法同步/异步无效!

非常困惑。Web API应用程序不需要异步吗?为什么推荐?

这不是那么简单。

有一个叫做线程池的东西。对应用程序的每个请求都将分配给从线程池中取出的单独线程。这是一个请求不阻止另一个请求的第一个原因。

现在,当您流量较低时,一切都很好,因此您不会击中线程池中的线程数量。但是...

为了讨论,假设您的请求平均需要1秒钟,并且您的尺寸量= 100。那个,由于它没有线程池要分配给它,因此必须等待第100个请求才能完成,将线程释放回线程池,然后可以处理。

现在,根据您的请求的作用,异步可以提供帮助(但也可能引起问题,所以不要盲目使用它!):

  1. 如果您的请求进行I/O操作(网络调用,文件系统,DB异步等),则这些操作在I/O线程上工作。这些不是来自线程池。因此,想象一下提出的请求,并发射一个网络调用或文件读取为0.93秒的请求。实际上,这意味着,如果您不使用异步,则您的线程池线程对0.93秒无用,它只是坐在那里等待IO线程完成。在这种情况下,async可以非常有用,因为一旦击中await关键字(与使用IO线程的操作一起使用),它将立即从线程池中释放线程,以便可以服务下一个请求。IO操作完成后,它将从线程池中获得线程以服务响应。

  2. 如果您的请求不使用任何IO操作,但您迫使它们使用异步(有很多方法可以做)提取另一个请求)(将需要操作运行)。在这种情况下,您只会创建开销并失去性能。

但是,无论如何,我有一种与您的问题无关的感觉。在上述2个方案中,您的方法是在两个单独的请求中运行的,并且与async/await无关,但是与服务器环境独立处理请求。

最新更新