用Parallel.ForEach替换顺序foreach

时间:2013-08-05 18:09:14

标签: c# parallel-processing

在下面的foreach p : allPersons中,很清楚(因为逻辑是连续的)地图/字典可以用于缓存/记忆。

Dictionary<string, int> personNameToIdMap = new Dictionary<string, int>();

foreach(p : allPersons)
{

 int outputId;

 if(personNameToIdMap.TryGetValue(p.Name, out outputId))
 {
   // nothing to do since map contained the p.Name
 }
 else
 { 
    outputId = doExpensiveLookup(p.Name);
    personNameToIdMap[p.Name] = outputId;
 }

  ...

  p.Id = outputId;

}

如果我将上述foreach替换为Parallel.ForEach,每个帖子会共享personNameToIdMap吗?

2 个答案:

答案 0 :(得分:5)

是的,如果Parallel.Foreach,每个帖子将使用Dictionary的相同实例。

如果您真的想要并行,可以使用ConcurrentDictionary Dictionary

的线程安全版本

答案 1 :(得分:2)

Harris完全正确 - ConcurrentDictionary<T,U>将是正确的做法。鉴于此,您可能希望稍微更改您的方法以利用ConcurrentDictionary的{​​{3}}方法:

ConcurrentDictionary<string, int> personNameToIdMap = new ConcurrentDictionary<string, int>();

Parallel.ForEach(allPersons, p =>
{
    int outputId = personNameToIdMap.GetOrAdd(p.Name, name => doExpensiveLookup(p.Name));

    // ...
    p.Id = outputId;
}