我的课本说:
是否需要运行成百上千的并发I / O绑定 操作,基于线程的方法会消耗数百或数千个 MB的内存纯粹是线程开销。
和
当并行运行多个长时间运行的任务时,性能可以 受苦,那么基于线程的方法更好
我很困惑,非线程池线程的开销和线程池线程的开销有什么区别?开销与I / O绑定有何关系?
最后,为什么基于线程的方法(例如,使用new Thread(runMethod).Start()
)更适合长时间运行的任务?
答案 0 :(得分:0)
ThreadPool
的可重用线程数量有限。该线程用于任务(例如Task.Run
)。执行较长时间的任务将阻塞线程,因此无法将其重用于另一个Task
。因此,为了始终有足够的ThreadPool
个线程可用(例如,用于异步/等待,Parallel Linq等),您应使用ThreadPool
个独立线程来执行此类任务。
为此,您可以使用Task.Factory.StartNew(Action, TaskCreationOptions)
(或接受TaskCreationOptions
对象的任何其他重载),然后传递参数TaskCreationOptions.LongRunning
。 LongRunning
强制创建一个独立于ThreadPool
的新线程。
因此,对于所有长时间运行且基于IO的任务,例如读取文件或数据库,应该通过调用ThreadPool
使用Task.Factory.StartNew(() => DoAction(), TaskCreationOptions.LongRunning);
个独立线程。您根本不需要new Thread(runMethod).Start()
。
ThreadPool
线程可重复使用,因此资源效率更高。因此,在检索ThreadPool
线程时,它们已经创建。创建新线程始终会占用大量资源。需要注册它们,必须创建调用堆栈,必须复制本地等等。这就是为什么在考虑性能时,只要工作量轻巧(短期运行),可重用线程是更好的选择。