2011-11-10 14 views
2

私はある種のキーと値のペアを持つクラスを作成しています。現在、次のようなものがあります。静的コレクションへのスレッドセーフなアクセス

private static Dictionary<Type, List<PropertyInfo>> PropertyCache { get; set; } 

これはスレッドセーフな方法で実装する正しい方法ですか?何らかの理由で、にstaticの効果について私に悩まされることがあります。これが正しければ、コードの残りの部分でそれを避けることができるように、間違った方法を示すことができます。

また、読み取り専用する必要があります(私は今までのコレクションから物事を追加・削除するつもりですか)?

それは違いを行った場合、プロパティは常にprivate宣言されます。ジョンスキートで

次の議論:事前に

おかげで

タグ付けされたC#が、VBで回答はOKです、私は "バイリンガル" はそう

EDITを話すようにしていますが、彼の答えのコメントでは、使用は次のようになります:

// I will do this 
PropertyCache.Add(typeof(string), new List<PropertyInfo>()); 
PropertyCache.Remove(typeof(string)); 

// I will never do this 
PropertyCache = new Dictionary<Type, List<PropertyInfo>>(); 

私はコレクションを繰り返し処理することはなく、キーだけでアクセスできます。

+1

「コレクションからアイテムを削除するだけです」とはどういう意味ですか? –

+0

@SteveDanner、私は決して行くつもりはない 'PropertyCache =新しい辞書>' 'PropertyCache.Add(item)'のみ: –

+0

これで、ReadOnlyDictionaryはうまくいきません。ジョン・スケートの答え、IMOを考えてみましょう。 –

答えて

1

は、インスタンスのメンバーよりもクロススレッドのアクセス権を持っている可能性が高くなります。 staticは、何かが複数のスレッドで使用するのが安全であるという意味ではなく、定義されているオブジェクトの複数のインスタンス間でオブジェクトが共有されていることを意味します。 ICollectionインタフェースを実装

コレクションは、コレクションが変更させるような一連の命令を実行することができますが、一度に一つだけのスレッドを保証するためにlockオブジェクトに使用することができますSyncRootにアクセスするためにキャストすることができます。このマニュアル(または古い学校の方法)に加えてUsing SyncRoot for Multithreaded Applications

lock(((ICollection)myObject).SyncRoot) 
{ 
    //Code that should be executed by only one concurrent thread 
    //This is add/insert/remove/iterate/clear/etc. 
} 

は基本的にこれを行うが、他のいくつかの特別なチェックと.NET 4で同時に使用できるオブジェクトがあります。ほとんどの場合、これらのオブジェクトは、完全に安全なオブジェクトの場合と同様に、パフォーマンスが最適化されています。オブジェクトに対して非常に制御された小さな一連のアクション(1つの追加メソッド、1つの削除メソッドがあり、コレクション全体を列挙しないで特定の既知のエントリにアクセスするだけの場合)では、上記の軽量の lock()の例を使用できますより良いパフォーマンスを得る。

これは特にコレクションに複数のオブジェクトを一度に追加する場合に表示されます。並行オブジェクトを使用すると、各追加操作はロックとロック解除を伴うアトミックです。これをタイトなループで実行すると、何度もロックを取得するパフォーマンスが低下します。別のスレッドが読み取ろうとしている場合、アクセスの競合が少し高くなります。自分でlockステートメントを使用する場合は、ロックを取得し、速くタイトなループでオブジェクトを追加してからロックを解除することができます。オブジェクトにアクセスしたいスレッドはもう少し長く待つでしょうが、全体的に操作が速く終わるはずです。また、相違点は一般的に非常に低いので、実際にはそれほど価値がなく、ほぼすべてのケースで時期尚早最適化のカテゴリに入ると考えてください。

3

あなたは、おそらくそれは読み取り専用あなたははい、変数の値を変更する必要がありますしない限り、行う必要があります。

は、.NET 4を使用している場合は、ConcurrentDictionaryを使用することを検討すべきである - そう、私はおそらく、単純に各アクセスのためにロックを取得アクセサを記述します。あなたはReaderWriterLockSlimなどを使用することができますが、私は個人的には、まずは簡単な安全な方法で始めます。スレッドセーフな方法で、辞書の内容を反復

注意がトリッキーになります - うまくいけば、あなたががあることは必要ありません。

+0

ありがとうございました。 「最も簡単な安全なアプローチ」の意味を広げることができますので、Net 35アプリケーションでもこれを実装する方法について考えています。 –

+0

@SBlackler:最も簡単な方法は、各アクセスをロックすることです。例で編集します。 –

+0

@SBlackler:実際には、値がリストであることに気がつきました。スレッドセーフではありません。どのようにこれを使うつもりですか?読み込まれると、リストは読み取り専用になりますか? –

0

あなたが示したことは決してスレッドセーフではありません。複数のスレッドが同時に項目を挿入または削除できる場合は、潜在的な問題があります。メンバーstaticを作る

関連する問題