代码之家  ›  专栏  ›  技术社区  ›  Vin

在Parallel中使用标签。每一个?

  •  8
  • Vin  · 技术社区  · 16 年前

    我有一个平行。ForEach循环在体内进行密集操作。

    该操作可以使用哈希表来存储值,并且可以重复用于其他连续的循环项。在密集操作完成后,我添加到Hashtable中,下一个循环项可以在Hashtable中查找并重用对象,而不是再次运行密集操作。

    Hashtable myTable = new Hashtable;
    Parallel.ForEach(items, (item, loopState) =>
    {
        // If exists in myTable use it, else add to hashtable
        if(myTable.ContainsKey(item.Key))
        {
           myObj = myTable[item.Key];
        }
        else
        {
           myObj = SomeIntensiveOperation();
           myTable.Add(item.Key, myObj); // Issue is here : breaks with exc during runtime
        }
        // Do something with myObj
        // some code here
    }
    

    4 回复  |  直到 16 年前
        1
  •  18
  •   Sam Harwell    16 年前

    System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>

    ConcurrentDictionary<T,K> cache = ...;
    Parallel.ForEach(items, (item, loopState) =>
    {
        K value;
        if (!cache.TryGetValue(item.Key, out value))
        {
            value = SomeIntensiveOperation();
            cache.TryAdd(item.Key, value);
        }
    
        // Do something with value
    } );
    

    如果元素在 items item.Key SomeIntensiveOperation 可能会因为那把钥匙被打两次电话。在该示例中,密钥未传递给 某种密集型操作 ,但这意味着“用值做点什么”代码可以执行键/值A和键/值B对,并且只有一个结果会存储在缓存中(也不一定是SomeIntensiveOperation计算的第一个结果)。你需要一个平行的懒惰工厂来处理这个问题 如果 这是个问题。此外,出于显而易见的原因,SomeIntensiveOperation应该是线程安全的。

        2
  •  4
  •   Hannoun Yassir    16 年前
        3
  •  3
  •   joshperry    16 年前

    ReaderWriterLockSlim on MSDN

    我想我会写一些代码。..

    ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
    Hashtable myTable = new Hashtable();
    Parallel.ForEach(items, (item, loopState) =>
    {
        cacheLock.EnterReadLock();
        MyObject myObj = myTable.TryGet(item.Key);
        cacheLock.ExitReadLock();
    
        // If the object isn't cached, calculate it and cache it
        if(myObj == null)
        {
           myObj = SomeIntensiveOperation();
           cacheLock.EnterWriteLock();
           try
           {
               myTable.Add(item.Key, myObj);
           }
           finally
           {
               cacheLock.ExitWriteLock();
           }           
        }
        // Do something with myObj
        // some code here
    }
    
    static object TryGet(this Hashtable table, object key)
    {
        if(table.Contains(key))
            return table[key]
        else
            return null;
    }
    
        4
  •  1
  •   Dario    16 年前

    另一种选择是允许词典不同步。竞争条件不会损坏字典,它只需要代码进行一些多余的计算。分析代码,检查锁或缺失的记忆是否会产生更糟糕的影响。