我一直在研究处理多线程.NET应用程序的不同方法。它变得有点混乱。
新线程->当需要一个附加线程时?
ThreadPool->需要多个线程时。使用现有线程并将优化(基于所涉及工作的数量)留给框架使用会更便宜。
任务->当您需要其他线程时,碰巧使用.net 4.0或更高版本。这是新线程的API吗?
Parallel.for->当您有多个任务并且希望框架处理优化以根据CPU内核数分配有关不同任务的工作时。
在MSDN上,它没有声明新的Thread方法已过时?
您对Thread
s和ThreadPool
用法的基本理解是正确的。Task
但是,要复杂一些。
线程,线程池,任务
首先,一个Task
简单地表示一个异步操作。它可以在ThreadPool
线程上执行(如果您是一个计划任务的人,那么通常它会像您TaskScheduler.Default
大部分时间一样使用)。它也可以在单独的非线程池线程上执行(当您指定时TaskCreationOptions.LongRunning
)。它甚至可以在没有线程的情况下执行(请考虑异步IO操作:http : //blog.stephencleary.com/2013/11/there-is-no-thread.html)。最后,当aTask
封装多个异步操作时,它可以是上述任何方法的组合。
最终Task
在Thread
和之上添加一个抽象层ThreadPool
(在适当时在内部使用,并且在计划任务时可以对此进行一定程度的控制)。Task
由于围绕它建立的语言支持,这三种线程方法应该是您选择的武器。Task
与使用低级线程工具执行异步操作序列相比,使用此控件可轻松进行。
这不,但是,意味着Thread
和ThreadPool
是真正过时-只是,他们不应该是你的电话对新开发的第一个点。抛开即使在使用时它们仍然被框架隐藏的事实Task
,请考虑使用Thread
或的全功能生产代码的数量ThreadPool
,以及一旦用这两种类型标记了它们会发生什么情况的ObsoleteAttribute
。一团糟。
当然,还有其他原因也要使用它们,例如,对性能非常敏感的场景(我敢肯定还有更多,但这就是我现在能想到的全部)。
使用Task安排工作
在安排新的计划时,关于何时使用ThreadPool
还是要考虑的问题Thread
仍然适用Task.
。这里的准则很简单:
TaskCreationOptions.LongRunning
在启动时指定标志是个好主意。这类似于启动新线程。ThreadPool
孔中Task.Run
(它使用默认的任务计划程序,该任务计划程序恰好ThreadPoolTaskScheduler
在当前实现中)。这类似于使用ThreadPool.QueueUserWorkItem(WaitCallback)
。平行
现在让我们讨论一下Parallel
类及其成员。首先,您具有Parallel.Invoke
,大致相当于并行启动一堆任务,然后在完成任务时阻塞。这仅在处理要并行运行的多个阻止操作时才真正有用。如果这是您的情况,并且您不想弄乱多个Task
实例,请使用它。
Parallel.For
与Parallel.ForEach
野兽略有不同,主要用于并行处理集合元素上受CPU约束的工作(由于它们内置的“负载平衡”的工作方式,因此将它们用于IO工作不是一个好主意,最终会产生太多线程除非您限制并行度)。这些方法在概念上不同于Thread
,ThreadPool
和Task
,并且更接近PLINQ。在并行化收集元素处理可显着提高性能的情况下,请在通常使用for
或foreach
循环的情况下使用它们。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句