When we use foreach
and Tasks
we need to use local variables like this:
List<Task> TaskPool = new List<Task>();
foreach (TargetType Item in Source)
{
TargetType localItem = Item;
TaskPool.Add(Task.Factory.StartNew(() => DoSomething(localItem)));
}
Task.WaitAll(TaskPool.ToArray());
But how about Parallel.Foreach
, I use it like this:
Parallel.ForEach(Source, (TargetType item) => DoSomething(item));
So there is not any Local Variable as you see. But how does Parallel.Foreach
work? Is there no need to introduce any local variables? or if needed, how can I define it?
UPDATE
Is there any difference in .NET 4 and .NET 4.5?
You do not define any local variable in Parallel.ForEach
- item
is nothing more than a formal parameter - the implementation code of Parallel.ForEach
is the one that will have to handle variables, and whether they are local, captured or something else.
There is no need to define a local variable related to the formal parameter Parallel.ForEach
- the caller code of your anonymous delegate will handle the variable and pass it to your function.
However in C#4, you might need to use a local variable if you capture another variable, that is:
void DoSomething(ItemType item, OtherType other) {
}
void YourFunction(IEnumerable<ItemType> items, IEnumerable<OtherType> others) {
foreach (var otherItem in others) {
var localOtherItem = otherItem;
Parallel.ForEach(items, item => DoSomething(item, localOtherItem));
}
}
You can see the difference above: localOtherItem
is taken from the context where the anonymous function is defined: that is called a closure. Whereas the items in items
are passed simply as a method parameter to the anonymous function.
In short: the item
in Parallel.ForEach
and the item
in C# foreach
are two very different problems.