ASP.NET中的线程处理和请求线程池

4
据说.NET Framework维护了一个线程池(.NET 4.5的默认值为5,000),用于处理ASP.NET请求。据说高并发长时间运行的请求会导致线程饥饿的情况,因此,对于高延迟调用,应该进行异步请求以释放请求线程。
但是,异步请求不是从线程池中生成另一个线程来完成工作吗?新线程是否来自与请求线程池不同的线程池?这些线程的创建数量是否有限制?

你有一些参考资料可以提供吗?例如一些例子、博客或者现实生活中的案例? - Aristos
1个回答

2
“但异步请求不会产生另一个线程池中的线程来完成它的工作吗?” “是的,但只有在异步工作完成后才会产生另一个线程。在工作进行时(通常意味着等待磁盘或网络),异步代码不会阻塞线程。”
“新线程来自与请求线程池不同的线程池,并且这些线程的数量是否有限制?” “ASP.NET没有单独的线程池。异步代码和ASP.NET使用相同的线程池,这意味着它们也共享相同的限制。”
“线程的限制并不是唯一的问题(如果是,您可以调用ThreadPool.SetMaxThreads()来增加它)。其他问题是每个线程使用1 MB的内存,这对于32位应用程序尤其成问题。此外,同时执行太多线程是低效的,因为需要进行上下文切换。”

你能详细说明一下“Yes, but only after the asynchronous work has been completed”吗?如果我将这个人为的例子作为异步方法,会怎样呢: Thread.Sleep(5000); int threadId = Thread.CurrentThread.ManagedThreadId; 根据你所说的,因为这个异步方法还没有完成,threadId会是null吗? - jodev
@jodev 不是的,但那不是真正的异步方法。你的方法会在整个5秒钟内阻塞一个线程。如果你改用 await Task.Delay(5000); int threadId = Thread.CurrentThread.ManagedThreadId;,那么在这5秒钟内,该方法将不使用任何线程。但下一行代码将在某个线程上执行,ManagedThreadId 永远不会返回 null 或类似的内容。 - svick
谢谢,现在更有意义了。 - jodev
一篇很棒的文章解释了异步任务不一定使用后台线程,可以在这里找到:http://blog.stephencleary.com/2013/11/there-is-no-thread.html - Sam Rueby

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接