1

在下文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;

}

如果我用 替换上面foreachParallel.ForEach内容,每个线程会共享personNameToIdMap吗?

4

2 回答 2

5

是的,如果Parallel.Foreach每个线程都将使用相同的Dictionary.

如果你真的想要并行性,你可以使用ConcurrentDictionary这是线程安全的版本Dictionary

于 2013-08-05T18:10:42.710 回答
2

哈里斯是完全正确的——ConcurrentDictionary<T,U>这将是正确的方法。鉴于此,您可能需要稍微更改您的方法以利用ConcurrentDictionary'GetOrAdd方法:

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;
}
于 2013-08-05T18:19:04.643 回答