Yan*_*hof 6 .net c# clr task-parallel-library
也许我不理解它...所有Parallel类问题:(
但是根据我现在正在阅读的内容,我理解当我使用Parallel时,我实际上调动了threadPool中存在的所有线程以执行某些任务/任务.
例如:
var arrayStrings = new string[1000];
Parallel.ForEach<string>(arrayStrings, someString =>
{
DoSomething(someString);
});
Run Code Online (Sandbox Code Playgroud)
因此,在这种情况下,Parallel.ForEach正在调动threadPool中存在的所有线程,用于"DoSomething"任务/任务.
但调用Parallel.ForEach会创建任何新线程吗?
很明显,没有1000个新线程.但是我们假设有1000个新线程,有些情况下threadPool会释放它所拥有的所有线程,在这种情况下...... Parallel.ForEach会创建任何新线程吗?
svi*_*ick 11
简短的回答:Parallel.ForEach()不是"动员所有线程".任何调度某些工作的操作ThreadPool(Parallel.ForEach()确实如此)都可能导致在池中创建新线程.
龙答:要正确地理解这一点,你需要知道如何三个层次抽象的工作:Parallel.ForEach(),TaskScheduler和ThreadPool:
Parallel.ForEach()(和Parallel.For())安排他们的工作TaskScheduler.如果未明确指定调度程序,则将使用当前调度程序.
Parallel.ForEach()在几个Tasks 之间分割工作.每个都Task将处理输入序列的一部分,一旦完成,它将请求另一个部分(如果有的话),依此类推.
有多少Task旨意Parallel.ForEach()创造?尽可能多的TaskScheduler意志让它运行.这样做的方法是每个人Task在开始执行时首先将自身的副本排入队列(除非这样做会违反MaxDegreeOfParallelism,如果你设置的话).这样,实际的并发级别就达到了TaskScheduler.
此外,第一个Task将实际执行当前线程,如果TaskScheduler支持它(这是使用完成RunSynchronously()).
默认的TaskScheduler只是每个入列Task到ThreadPool队列中.(实际上,如果你Task从另一个开始,它会更复杂Task,但这在这里并不相关.)其他TaskSchedulers可以完全不同的东西,其中一些(如TaskScheduler.FromCurrentSynchronizationContext())完全不适合使用Parallel.ForEach().
在ThreadPool使用一个相当复杂的算法来决定到底有多少线程应该在任何给定时间运行.但最重要的是调度新工作项可能会导致创建新线程(尽管不一定立即).因为有Parallel.ForEach(),总有一些项目排队执行,完全取决于内部算法ThreadPool来决定线程数.
综合起来,几乎不可能决定a将使用多少线程Parallel.ForEach(),因为它取决于许多变量.两种极端都是可能的:循环将在当前线程上完全同步运行,并且每个项目将在其自己的新创建的线程上运行.
但一般来说,应该接近最佳效率,您可能不必担心所有这些细节.