2016-05-27 1 views
0

リストを取り込むメソッドを使用して辞書を更新しています。このリストには、辞書に格納されている更新された値を指定する必要があります。例:私は値1,2,3,4を辞書に保存しています。スレッドは、リスト0,1,3,5を使用して辞書の値を更新しようとします。そのスレッド内の私の "リフレッシュ"メソッドは、辞書から2,4を削除し、0,5を追加する必要があります。C#threadはconcurrentdictionaryの内容を安全に「リフレッシュ」します

私は、この「リフレッシュ」をすばやく連続して実行しようとしているので、その操作が重複していないことを確認したいと思います。このため、次のスレッドに移る前に辞書を更新して操作を完了しようとする各スレッドが必要です。スレッドが更新しようとしている順序で辞書が更新されるようにする必要もあります。

私の現在のコードでは、スレッドは新しいリストを作成し、Refresh()を呼び出してSubscriptionCacheの辞書を更新します。新しいリストを作成する前に、各スレッドを3〜8msの間スリープさせてから、新しいリストを使用して辞書をリフレッシュします。

は、ここに私のコードを見てみます:

public static class SubscriptionCache 
    { 
     private static ConcurrentDictionary<int, Subscription> _firstPartySubscriptionIds = new ConcurrentDictionary<int, Subscription>(); 

     //This compares the contents of the dictionary and new list, 
     then updates the dictionary accordingly. 
     internal static void Refresh(IEnumerable<Subscription> firstPartySubscriptionIds) 
     { 
      lock(_firstPartySubscriptionIds) 
      { 
      try 
      { 
       Compare(firstPartySubscriptionIds, true).ForEach((s) => 
       { 
        var t = _firstPartySubscriptionIds.TryAdd(s.GetHashCode(), s); Print("Added" + s.SystemID + " Success: " + t + " With Key: " + s.GetHashCode()); 
       }); 

       Compare(firstPartySubscriptionIds, false).ForEach((s) => 
       { 
        var t = _firstPartySubscriptionIds.TryRemove(s.GetHashCode(), out s); Print("Removed" + s.SystemID + "Success: " + t + " With key: " + s.GetHashCode()); 
       }); 


       LastRefreshedOn = DateTime.Now; 
      } 
      catch { } 
      } 
     } 

     private static List<Subscription> Compare(IEnumerable<Subscription> firstPartySubscriptionIds, bool reverse) 
     { 
      var masterList = _firstPartySubscriptionIds.Values.ToList(); 
      var newList = firstPartySubscriptionIds.ToList(); 
      var returnList = new List<Subscription>(); 

      if (reverse == false) // Returns elements in the old list which are NOT in the new list 
      { 
       foreach (Subscription s in masterList) 
       { 
        if (!newList.Contains(s)) 
        { 
         returnList.Add(s); 
        } 
       } 
      } 
      else //Returns elements in the new list which are NOT in the old list 
      { 
       foreach (Subscription s in newList) 
       { 
        if (!masterList.Contains(s)) 
        { 
         returnList.Add(s); 
        } 
       } 
      } 
      return returnList; 
     } 
+1

シンプルなロッキングがパフォーマンス上の問題を引き起こしますか? – Evk

+0

コードを確認する必要があります。 – progpow

+0

@エヴァーク私はそれについて考えているので、私のプログラムはそれなしではどうやって動作するのかわかりません。私はこれが概念的に働く別の方法を考えることはできません。 –

答えて

1

ConcurrentDictionaryはちょうど魔法の複数のスレッドが動作関わるすべてのものがありません。これは、構造のすべてのメソッドを論理的に原子的にするだけです。単一のアトミック操作として複数の操作を実行したい場合は、明示的にスレッドを管理して(ロックすることによって)行う必要があります。

関連する問題