当 IIS 已经处理请求并发时,为啥要使用异步控制器?
Posted
技术标签:
【中文标题】当 IIS 已经处理请求并发时,为啥要使用异步控制器?【英文标题】:Why use async controllers, when IIS already handles the request concurrency?当 IIS 已经处理请求并发时,为什么要使用异步控制器? 【发布时间】:2014-08-11 09:15:35 【问题描述】:我想知道为什么我要在控制器上使用异步任务,而 IIS 已经为我处理了并发?
http://msdn.microsoft.com/en-us/library/dd560842.aspx
【问题讨论】:
【参考方案1】:asp.net 中的异步/等待不是关于并发,而是关于阻塞或不阻塞线程。
如果您使用 async / await 您在等待操作时释放线程。如果此操作受 CPU 限制,则没有任何好处(由于上下文切换,它甚至会稍微慢一些)
如果操作是受 IO 限制的(网络、磁盘等),这意味着 IIS 可以处理更多并发请求,因为您不会阻塞任何不做任何事情的线程。
【讨论】:
好的,但是我有无限线程('maxConcurrentThreadsPerCPU="0" ') 那我为什么要关心释放它们呢? 我不相信你有无限的线程。 CLR 线程池将控制默认情况下可用的线程数。 msdn.microsoft.com/en-us/library/dd560842(v=vs.110).aspx "默认这个设置是0,也就是说ASP.NET不限制每个CPU可以创建的线程数,虽然CLR线程池也限制了可以创建的线程数。"跨度> 没有“无限”之类的东西。每个线程都会消耗大量资源。除非您拥有无限的资源,否则您不会拥有无限的线程。【参考方案2】:正如其他人所指出的,async
允许请求线程在执行异步操作时返回线程池。使用同步处理程序,您的服务器最终会在 I/O 上阻塞线程,基本上没有做任何重要的事情,但也无法在被阻塞时用于其他请求。 async
只是释放这些线程,以便它们一直有用。
所以,首先要注意的是“async
or 线程池”这个问题是错误的问题。当您使用async
时,您允许 ASP.NET 最大限度地利用现有线程池。 async
采用 ASP.NET 中现有的(并行)并发,并添加(异步)并发以实现更大的可扩展性。
但问题仍然是“为什么”?原因有两个:async
可以比(仅)线程池扩展得更远,async
的响应速度也更快。正如其他答案的 cmets 中所提到的,线程是非常重量级的对象,可以不必要地浪费;异步操作的内存远小于线程使用的内存。第二个原因也很重要:当突然爆发的请求进来时,线程池(本身)只能以有限的速度扩展; async
使线程池能够更有效地处理突发请求。
【讨论】:
【参考方案3】:在处理请求时,您可能会访问可能需要大量时间的资源(例如,往返数据库可能需要数十毫秒,通常更慢)。
如果您使用同步操作来获取这些资源,则处理线程将被阻塞,直到该 IO 完成。
使用异步操作允许在 IO 完成时将同一 IIS 线程用于更有用的事情。在负载较高的网站中,这可能是显着的可扩展性差异。
【讨论】:
好的,但是我有无限线程('maxConcurrentThreadsPerCPU="0" ') 那我为什么要关心释放它们呢? @realPro 每个线程都是重要的附加资源。 1MB 的地址空间用于堆栈,调度程序的额外负载开始增加,尤其是当有大量切换时(大多数请求将是 IO 绑定的)。以上是关于当 IIS 已经处理请求并发时,为啥要使用异步控制器?的主要内容,如果未能解决你的问题,请参考以下文章