如果源为空,Parallel.ForEach是否启动线程?

Álv*_*cía 5 c# task-parallel-library

我用Parallel.ForEach这样的方式:

public void myMethod(IEnumerable<MyType> paramIeCollection)
{
    Parallel.Foreach(paramIeCollection,
          (iterator) =>
          {
              //Do something
          });
}
Run Code Online (Sandbox Code Playgroud)

我想知道什么时候paramIeCollection是空的,Parallel.ForEach无论如何都是启动并从线程池中获取线程并消耗资源,或者如果它首先检查集合中是否有项目.

如果没有检查,为了避免这种情况,我在想这个代码:

if(paramIeCollection.count > 0)
{
    //run Parallel.Foreach
}
Run Code Online (Sandbox Code Playgroud)

所以问题是,在调用之前检查集合是否有项目Parallel.ForEach或是否需要它是一个好的做法?

AAA*_*ddd 9

事实是知道它确实检查.但是,如果您通过源代码,那么在它确定之前会有一些其他的检查和平衡.

如果您有处理器指令OCD,事先进行简单的检查if(list.count > 0)可能会为您节省一堆IL.然而在现实世界中,它不会产生太大的影响

System.Threading.Tasks 参考来源

例如,对于Simple IEnumberable重载,您可以通过Eg跟踪源代码

public static ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)
Run Code Online (Sandbox Code Playgroud)

致电ForEachWorker

private static ParallelLoopResult ForEachWorker<TSource, TLocal>(
        IEnumerable<TSource> source,
        ParallelOptions parallelOptions,
        Action<TSource> body,
        Action<TSource, ParallelLoopState> bodyWithState,
        Action<TSource, ParallelLoopState, long> bodyWithStateAndIndex,
        Func<TSource, ParallelLoopState, TLocal, TLocal> bodyWithStateAndLocal,
        Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
        Func<TLocal> localInit, Action<TLocal> localFinally)
Run Code Online (Sandbox Code Playgroud)

内联呼叫

// This is an honest-to-goodness IEnumerable.  Wrap it in a Partitioner and defer to our
        // ForEach(Partitioner) logic.
return PartitionerForEachWorker<TSource, TLocal>(Partitioner.Create(source), parallelOptions, body, bodyWithState,
            bodyWithStateAndIndex, bodyWithStateAndLocal, bodyWithEverything, localInit, localFinally);
Run Code Online (Sandbox Code Playgroud)

PartitionerForEachWorker

// Main worker method for Parallel.ForEach() calls w/ Partitioners.
private static ParallelLoopResult PartitionerForEachWorker<TSource, TLocal>(
        Partitioner<TSource> source, // Might be OrderablePartitioner
        ParallelOptions parallelOptions,
        Action<TSource> simpleBody,
        Action<TSource, ParallelLoopState> bodyWithState,
        Action<TSource, ParallelLoopState, long> bodyWithStateAndIndex,
        Func<TSource, ParallelLoopState, TLocal, TLocal> bodyWithStateAndLocal,
        Func<TSource, ParallelLoopState, long, TLocal, TLocal> bodyWithEverything,
        Func<TLocal> localInit,
        Action<TLocal> localFinally)
Run Code Online (Sandbox Code Playgroud)

最终检查

while (myPartition.MoveNext())
Run Code Online (Sandbox Code Playgroud)