2011-06-20 7 views
4

私は、個々のアイテムがイベントを発生させてその結果をイベントargsで返すので、読み込みや更新はほとんど行われない軽く使われた辞書を持っています。実際、スレッドは常に同じスレッドで更新されます。安全のために単純なロックを追加することを考えていました。私はちょうど私がアクセサを取得するにロックを配置することができますかと思っていた。これは機能しますか?getアクセサにコレクションをロックすることはできますか?

 Dictionary<string,Indicator> indicators = new Dictionary<string,Indicator>(); 
     Dictionary<string, Indicator> Indicators 
     { 
      get 
      { 
       lock (indicators) 
       { 
        return indicators; 
       } 
      } 
     } 

     public void AddIndicator(Indicator i) 
     { 
      lock (indicators) 
      { 
       indicators.Add(i.Name, i); 
      } 
     } 

答えて

6

これは特に役に立たないものではありません。特に

、あなたが持っている場合:

x = foo.Indicators["blah"] 

を、それはスレッドセーフではありませんので、その後インデクサが...ロックを保持してのないスレッドを実行されます。上記のコードを次のように考えてください:

Dictionary<string, Indicator> indicators = foo.Indicators; 
// By now, your property getter has completed, and the lock has been released... 
x = indicators["blah"]; 

インデクサー経由でアクセスする以外に何かする必要はありますか?ない場合は、あなただけの方法でプロパティを置換する場合があります

public Indicator GetIndicator(string name) 
{ 
    lock (indicators) 
    { 
     return indicators[name]; 
    } 
} 

(あなたがなど、代わりにTryGetValueを使用することをお勧めします - それはあなたが達成しようとしているかに依存します。)個人的に

コレクションの参照をロックするのではなく、私的に所有されていてロックされていないロックオブジェクトへの参照を使用することをお勧めしますが、これは別の問題です。

他の場所で述べたように、あなたは.NET 4を使用している場合ConcurrentDictionaryはあなたの友人であるが、もちろん、それはその前に利用できません:(

Jonの入力以外に
0

短い答え:はい。
Jonが言及しているように、インデックスを使用するときに意図したとおりにロックされないのはなぜですか。

+3

これは「配列アクセス」ではなく、インデクサーです。しかしもっと重要なのは、あなたがそれを使って何をしていたとしても、あなたが参照を取得した時点でロックが解放されるということです。 –

+0

@jon:ヒントをいただきありがとうございます。私は現在、配列アクセスと呼ばれるPHPをプログラミングしています... – ChrFin

4

、私はないと言うだろうMSDNから、とにかくコレクションindicators自体をロック:

ご注意くださいVisual BasicでC#または SyncLock(Me)の中で(この)、インスタンス上の例のロックの をロックする際に、アプリケーション内の他の コード場合は、。外部の の外部にオブジェクトがロックされていると、デッドロックが発生する可能性があります( )。

専用のobjectインスタンスを使用してロックすることをお勧めします。これがさらに詳しい情報と理由でカバーされている場所は他にもあります。なぜなら、ここでさえ、あなたが時間があるときに情報を検索する必要があるからです。

+0

私はちょうど私の自身の答えに似た何かを追加していました:) –

+0

@ジョン:確かに、あなたは良いカバレッジを提供するには不足しているとは思わなかった - –

+0

私はあなたの答えをまったく非難しようとしていませんでした - ちょうどタイミングの偶然に注意してください:) –

3

また、スレッドセーフティを処理するConcurrentDictionaryを使用することもできます。