2012-02-22 9 views
0

私はシングルトンオブジェクトを持ち、そこに辞書が定義されています。シングルトンオブジェクト内の辞書オブジェクトにアクセスする複数のタイマー

ここでは、MyDictionaryを更新するSystem.Timers.Timerオブジェクトが2つあります。

System.Timers.Timer timer1 = new System.Timers.Timer(5); 
timer1.AutoReset = false; 
timer1.Elapsed += new System.Timers.ElapsedEventHandler(MyTimer1Handler); 
timer1.Enabled = true; 
timer1.Start(); 

System.Timers.Timer timer2 = new System.Timers.Timer(5); 
timer2.AutoReset = false; 
timer2.Elapsed += new System.Timers.ElapsedEventHandler(MyTimer2Handler); 
timer2.Enabled = true; 
timer2.Start(); 

private void MyTimer1Handler(object sender, ElapsedEventArgs e) 
{ 
    MyClass.Instance.MyDictonary[1] = 100; 
} 

private void MyTimer1Handler(object sender, ElapsedEventArgs e) 
{ 
    MyClass.Instance.MyDictonary[2] = 100; 
} 

私の質問は、タイマーの経過イベントハンドラを考慮すると、今で指数1とMyDictionaryのインデックス2に一意に動作し、私はMyDictionary上の任意のロックが必要なのでしょうか?

答えて

5

はい、する必要があります。読ん言う

http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

はスレッドセーフですが、編集はできません。また、Dictionaryを反復することは本当に安全ではないとも言います。

.NET 4を使用できる場合は、スレッドセーフであるConcurrentDictionaryを使用できます。あなたが投稿することは、この具体的な例

http://msdn.microsoft.com/en-us/library/dd287191.aspx

+0

Splendid。私はConcurrentDictionaryが好きです。どうもありがとう。 – user977606

1

、はいあなたがする必要はありますが、厳密に言えば、それはあなたの使用パターンに応じて、必ずしも必要ではありません。

たとえば、2つのキーがあらかじめ設定されている場合、一方のスレッド操作が他方のスレッド操作の状態に影響していない場合は、辞書の共有状態は変更されません。たとえば、キーを追加/削除していないことが分かっている場合、各スレッドは特定のキーにアクセスします。あなたは辞書の各キーの値は反復した後になると思いますか何

class Program 
{ 

    static Dictionary<string, int> _dictionary = new Dictionary<string, int>(); 

    static void Main(string[] args) 
    { 
     _dictionary["key1"] = 0; 
     _dictionary["key2"] = 0; 

     Action<string> updateEntry = (key) => 
      { 
       for (int i = 0; i < 10000000; i++) 
       { 
        _dictionary[key] = _dictionary[key] + 1; 
       } 
      }; 

     var task1 = Task.Factory.StartNew(() => 
      { 
       updateEntry("key1"); 
      }); 

     var task2 = Task.Factory.StartNew(() => 
     { 
      updateEntry("key2"); 
     }); 

     Task.WaitAll(task1, task2); 

     Console.WriteLine("Key1 = {0}", _dictionary["key1"]); 
     Console.WriteLine("Key2 = {0}", _dictionary["key2"]); 

     Console.ReadKey(); 
    } 
} 

は、我々は単に並列に2与えられたキーの前の値をインクリメントされ、次の簡単な例を考えてみましょう2回個別スレッドループ内で同じ辞書に1000万回以上同じ辞書がありますか?

さてあなたは

Key1 = 10000000 
Key2 = 10000000 

を得る余分な同期は単に辞書で既存のキーに値を割り当てるために、上記の例では必要ありません。あなたがキーを追加または削除したい場合は、あなたのケースでは、このようなConcurrentDictionary<TKey,TValue>

などのデータ構造を同期するか、使用することを検討する必要が

もちろん、あなたは実際に辞書に値を追加しているので、あなたがする必要はあり何らかの形の同期を使用します。

関連する問題