C# 为什么使用ThreadPool比基于线程的方法有优势?

C# 为什么使用ThreadPool比基于线程的方法有优势?,c#,.net,clr,C#,.net,Clr,我的课本上说: 您是否需要运行数百或数千个并发I/O绑定 操作时,基于线程的方法会消耗数百或数千个线程 MB内存纯粹是线程开销 及 当并行运行多个长时间运行的任务时,性能会受到影响 因此,基于线程的方法更好 我很困惑,非线程池线程的开销和线程池线程的开销有什么区别?开销与I/O绑定的关系如何 最后,为什么基于线程的方法(例如,使用新线程(runMethod).Start())更适合长时间运行的任务 ThreadPool的可重用线程数量有限。此线程用于任务(例如,Task.Run)。执行时间较长的

我的课本上说:

您是否需要运行数百或数千个并发I/O绑定 操作时,基于线程的方法会消耗数百或数千个线程 MB内存纯粹是线程开销

当并行运行多个长时间运行的任务时,性能会受到影响 因此,基于线程的方法更好

我很困惑,非线程池线程的开销和线程池线程的开销有什么区别?开销与I/O绑定的关系如何


最后,为什么基于线程的方法(例如,使用
新线程(runMethod).Start()
)更适合长时间运行的任务

ThreadPool
的可重用线程数量有限。此线程用于任务(例如,
Task.Run
)。执行时间较长的任务会阻塞线程,使其无法重新用于另一个
任务
。因此,为了始终有足够的
ThreadPool
线程可用(例如,对于异步/等待、并行Linq等),您应该为此类任务使用
ThreadPool
独立线程。
您可以使用
Task.Factory.StartNew(Action,TaskCreationOptions)
(或接受
TaskCreationOptions
对象的任何其他重载),然后传入参数
TaskCreationOptions.LongRunning
<代码>长时间运行
强制执行独立于
线程池的新线程

因此,对于所有长时间运行和基于IO的任务,如读取文件或数据库,您应该通过调用
Task.Factory.StartNew(()=>DoAction(),TaskCreationOptions.LongRunning)来使用
ThreadPool
独立线程。您根本不需要
新线程(runMethod).Start()


ThreadPool
线程资源效率更高,因为它们是可重用的。因此,当检索
ThreadPool
线程时,它们已经被创建。创建新线程总是耗费大量资源。它们需要注册,必须创建调用堆栈,必须复制本地线程,等等。这就是为什么在考虑性能时,最好选择可重用线程,只要工作负载较轻(短时间运行)。

这有点过于宽泛和脱节。似乎也有一点缺少背景。我认为与其问这样的问题,不如研究任务、线程和线程池“为什么基于线程的方法(例如,使用Task.Run())更适合于长时间运行的任务”,这不是一种“基于线程的方法”,因为Task.Run()将使用线程池。“基于线程”将是
threadt=新线程(runMethod);t、 Start()“当并行运行多个长时间运行的任务时,性能可能会受到影响,那么基于线程的方法更好”这样想:池中有n个线程,准备好执行任务。现在,如果您用一个长时间运行的任务阻止其中一个,那么您只剩下n-1个任务。如果为长时间运行的任务创建一个单独的线程,则仍然有n个线程。如果额外的线程长时间运行,那么可以接受额外的开销。“开销与I/O绑定的关系如何?”在I/O绑定的任务上,没有开销,因为。等待IO的任务将释放该线程,并且当IO准备就绪时,可以(也可以不)在同一个或另一个线程上继续。(当然,我假设您
wait
某种异步IO方法)
ThreadPool
的可重用线程数量有限。此线程用于任务(例如,
TaskRun
)。执行时间较长的任务将阻止无法再用于另一个
任务的线程。因此,为了始终有足够的
ThreadPool
线程可用(例如对于
async/await
、并行Linq等),您应该使用
ThreadPool
独立线程来执行此类任务。