睡在一个混合的C#线程中

时间:2011-06-10 11:37:41

标签: c# multithreading threadpool sleep

在关于C#中线程的this网络教程中,Joseph Albahari写道:“不要在汇集的线程中睡觉!”你为什么不这样做?它对性能的影响有多严重? (这不是我想要做的;我只是好奇。)

3 个答案:

答案 0 :(得分:13)

线程池中只有有限数量的线程;线程池旨在有效地执行大量任务。它们依赖于每个任务快速完成,以便线程可以返回池并用于下一个任务。

因此,在线程池线程中休眠会使池中的数据不足,最终可能会耗尽可用线程,并且无法处理分配给它的任务。

答案 1 :(得分:6)

线程池旨在快速在不同的线程上执行相对较短的任务,而无需花费创建新线程的成本。线程池具有最大线程数,一旦达到该线程,任务就会排队,直到线程可用。

因此,在线程池上休眠的线程会占用队列,或者导致线程池耗尽。

答案 2 :(得分:5)

线程是一个重量级的对象。
创建新线程需要大量资源,例如为托管堆栈分配1 MB,创建托管线程对象,内核堆栈,内核线程对象,用户线程环境块。这都需要时间和记忆。因此,您不希望真正快速地创建和销毁对象。此外,一旦你有多个线程上下文切换也需要一些资源

线程池是CLR可以放置未使用的线程的地方,以防您的应用程序需要它。
Threadpool最初包含0个线程,一旦您从池中请求线程,该池将快速创建为池定义的最小线程数。大约2分钟后,未使用的线程被杀死。但是如果负载增加并且您需要更多线程,则线程池将慢慢创建新线程,直到达到最大绑定。您不能拥有超过最大值的线程,所有新请求将在工作线程返回池后排队并执行。在更糟糕的情况下,您可以获得OutOfMemoryException

如果从池中取出的线程被阻止,则:

  • 持有资源
  • 不做任何有价值的工作,而应用程序可能需要此线程来处理新请求
  • 通过引入块来打破可扩展性