【问题标题】:Threading in ASP.NET and the request thread poolASP.NET 中的线程和请求线程池
【发布时间】:2013-06-01 16:51:00
【问题描述】:

假设 .NET Framework 维护一个线程池(.NET 4.5 的默认值为 5,000),用于为 ASP.NET 请求提供服务。据说具有高并发长时间运行请求的大型应用程序可能会导致称为线程饥饿的情况。因此,应该为高延迟调用发出异步请求以释放请求线程。

但是异步请求不会从线程池中产生另一个线程来完成它的工作吗?新线程是否来自与请求线程池不同的池,这些线程的创建数量是否有限制?

【问题讨论】:

  • 你有一些参考,一些例子,一些博客,一些来自现实生活的东西吗?

标签: asp.net async-await


【解决方案1】:

但是异步请求不会从线程池中产生另一个线程来完成它的工作吗?

是的,但只有在异步工作完成之后。在工作完成时(通常意味着等待磁盘或网络),异步代码不会阻塞线程。

新线程是否来自与请求线程池不同的池,这些线程的创建数量是否有限制?

ASP.NET 没有单独的线程池。异步代码和 ASP.NET 使用相同的线程池,这意味着它们也共享相同的限制。

线程限制并不是唯一的问题(如果是,您可以调用ThreadPool.SetMaxThreads() 来增加它)。其他问题是每个线程使用 1 MB 内存,这对于 32 位应用程序尤其成问题。此外,由于上下文切换,同时执行太多线程效率低下。

【讨论】:

  • 您能否详细说明“可以,但只有在异步工作完成之后”?如果我将这个人为的示例用作异步方法会怎样:Thread.Sleep(5000); int threadId = Thread.CurrentThread.ManagedThreadId;根据您的说法,threadId 是否会因为此异步方法尚未完成而为 null?
  • @jodev 不,但这不是真正的异步方法。您的方法将阻塞一个线程整整 5 秒。如果您改为使用await Task.Delay(5000); int threadId = Thread.CurrentThread.ManagedThreadId;,那么在这 5 秒内,该方法将不会使用任何线程。但是下面的行会在某个线程上执行,ManagedThreadId 永远不能返回null,或者类似的东西。
  • 谢谢,更有意义。
  • 一篇很好的文章解释了异步任务如何必须使用后台线程可以在这里找到:blog.stephencleary.com/2013/11/there-is-no-thread.html
猜你喜欢
  • 2018-07-19
  • 2014-11-16
  • 2011-10-10
  • 2010-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多