我一直在用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个请求才能完成,将线程释放回线程池,然后可以处理。
现在,根据您的请求的作用,异步可以提供帮助(但也可能引起问题,所以不要盲目使用它!):
-
如果您的请求进行I/O操作(网络调用,文件系统,DB异步等),则这些操作在I/O线程上工作。这些不是来自线程池。因此,想象一下提出的请求,并发射一个网络调用或文件读取为0.93秒的请求。实际上,这意味着,如果您不使用异步,则您的线程池线程对0.93秒无用,它只是坐在那里等待IO线程完成。在这种情况下,
async
可以非常有用,因为一旦击中await
关键字(与使用IO线程的操作一起使用),它将立即从线程池中释放线程,以便可以服务下一个请求。IO操作完成后,它将从线程池中获得线程以服务响应。 -
如果您的请求不使用任何IO操作,但您迫使它们使用异步(有很多方法可以做)提取另一个请求)(将需要操作运行)。在这种情况下,您只会创建开销并失去性能。
但是,无论如何,我有一种与您的问题无关的感觉。在上述2个方案中,您的方法是在两个单独的请求中运行的,并且与async/await
无关,但是与服务器环境独立处理请求。