Parallel.Foreach vs Foreach and Task in local vari

2019-04-02 11:51发布

问题:

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?

回答1:

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.