我一直在编写我的 Web Api 控制器方法async
关键字并一直在使用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
端点。
我原本以为我会required使 Hello 方法异步,以便对 Goodbye 端点的请求能够立即返回。但是使这个方法同步/异步没有效果!
很困惑。 Web Api 应用程序不需要异步吗?为什么推荐?
事情没那么简单。
有一种东西叫做线程池。对应用程序的每个请求都会分配给从线程池中获取的单独线程。这是一个请求不会阻止另一个请求的第一个原因。
现在,当流量较低时,一切都很好,因此您不会达到线程池中线程的限制数量。但...
为了便于讨论,假设您的请求平均需要 1 秒,并且您的线程池大小 = 100。您将在第 101 个请求时开始遇到限制。那个,因为没有线程池分配给它,所以必须等待第 100 个请求完成,将线程释放回线程池,然后才能得到处理。
现在,根据您的请求的作用,异步可以提供帮助(但也可能导致问题,所以不要盲目使用它!):
-
如果您的请求执行 I/O 操作(网络调用、文件系统、数据库异步等),那么这些操作将在 I/O 线程上工作。这些不是来自线程池。因此,想象一下传入的请求并触发网络调用或文件读取,需要 0.93 秒。这实际上意味着,如果您不使用异步,那么您的线程池线程在 0.93 秒内没有任何用处,它只是坐在那里等待 IO 线程完成。
在那些情况下,async
可能非常有用,因为一旦它击中await
关键字(与使用 IO 线程的操作一起使用)它将立即从线程池中释放线程,以便可以处理下一个请求。
一旦IO操作完成,它就会从线程池中获取一个线程来提供响应。
-
如果您的请求不使用任何 IO 操作,但您强制它们使用异步(有多种方法可以做到这一点),那么您实际上要做的就是将一个线程池线程(用于接收请求的初始线程)交换为另一个线程池线程一个(将需要运行该操作)。在这种情况下,您只会产生开销并损失性能。
但是,无论如何,我有一种感觉与你的问题并不严格相关。
在上述两种情况中的任何一种中,您的方法都在两个单独的请求中运行,并且几乎与async/await
但在服务器环境中,请求是独立处理的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)