I am using a Parallel.ForEach
in this way:
public void myMethod(IEnumerable<MyType> paramIeCollection)
{
Parallel.Foreach(paramIeCollection,
(iterator) =>
{
//Do something
});
}
I am wondering if when paramIeCollection
is empty, the Parallel.ForEach
starts anyway and take threads from Thread Pool and consumes resources or if it first checks if there are items in the collection.
If it doesn't check, to avoid that, I am thinking in this code:
if(paramIeCollection.count > 0)
{
//run Parallel.Foreach
}
So the question is, is it a good practice to check if the collection has items before calling Parallel.ForEach
or if it isn't needed?
The truth be known it does check. However if you go through the source there are a handful of other checks and balances it does before it figures it out.
If you have processor instruction OCD, a simple check beforehand like if(list.count > 0)
will probably save you a bunch of IL. however in the real world it wont make much of a difference
System.Threading.Tasks
Reference Source
For instance, for the simple IEnumerable
overload, you can follow the source code through E.g
public static ParallelLoopResult ForEach<TSource>(IEnumerable<TSource> source, Action<TSource> body)
Calls 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)
Calls inline
// 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);
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)
Which eventually does the check
while (myPartition.MoveNext())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With