2012-03-20 6 views
3

Lookup<TKey, TElement>から複数のスレッドを読み込んでも安全ですか?複数のスレッドがLookup <TKey、TElement>から読み取ることは安全ですか?

Lookup<TKey, TElement>は不変である、しかしMSDN状態:(Visual BasicではShared)

この型のpublic staticメンバーは 、スレッドセーフです。どのインスタンスメンバーもスレッド が安全であるとは保証されません。

私はそれを想像するとぞっとするものの、MSDNのドキュメント を汲み出す機が誤っていることができれば、私は思ったんだけど。

+3

申し訳ありませんが、ここでの楽しみは許可されていないことを忘れていました。 –

+0

複数のスレッドが不変のデータ構造を読む際に問題を抱えている状況を想像できますか? – ChaosPandion

+0

@ChaosPandion MSDNはそれが言うことを言っているので、WhallahはStackOverflowに関する質問をしました。 –

答えて

0

これはあなたがおそらく気付いたように、 のすべての の標準の免責事項です。いくつかのメソッドはスレッドセーフであるかもしれませんが、 "保証されません"。

一般に、収集するライターがない場合、複数のスレッドを使用してコレクションから読み取ることは安全です。コレクションを同時に更新する必要がある場合は、SynchronizedKeyedCollectionのような適切な同期化またはスレッドセーフな組み込みのコレクションを使用してください。

+0

すべてのクラスにこの免責事項があります。 'Dictionary '、 'BlockingCollection '、 'Concurrentxxxx 'のどれかをチェックしてください。それらは、それらのオブジェクトとのやりとりの一部またはすべてが複数のスレッドから安全であることを知らせます。 –

+0

ありがとうございます。 "all"は "most"に置き換えられました。 –

0

書き込みがない限り、読み込みを行うだけでスレッドセーフです。これはどんな場合でも有効です。

あなたの質問はスレッドセーフという概念とは正反対です。書き込みまたは読み取りと組み合わせた書き込みはスレッドセーフではありませんが、書き込みのない複数の読み取りはスレッドセーフです。

スレッドセーフでないことが保証されていないインスタンスメンバーについては、スレッドセーフではないシナリオの場合にのみ有効です。これは定義上、書き込み操作を意味します。

+2

"書き込みがない限り、読み込みを行うのはスレッドセーフです。これはどんな場合でも有効です。" - それは真実ではない。メモリモデルについて考えてみましょう。たとえば、スレッドがすべてのエントリのデータを「参照」できるようになる前に、ルックアップを「参照」することは可能です。これは、メモリ障壁がどのように設定されているかによって異なります。 –

+0

私はそのクラスのメンバーから「読む」ときにそのクラスが内部的に何をしているのか分かりません。私は、ドキュメンテーションで「こんにちは、これをやるのは大丈夫です! –

+0

@Jon Skeet:はい、それは良い点です。私はそれが要件として可視性を含むかどうかにかかわらず、スレッドセーフの定義に依存していると思います。 – Tudor

1

私は1年後にあいまいなマルチスレッド関連のバグをデバッグしなければならない危険がありませんので、手動同期なしでこのクラスを使用することは安全ではないと想定します。

0

Lookup<TKey,TElement>は不変であるため、すべてのメンバーで同じ値が得られます。それがそこに保存されている項目を変更できないことを意味するものではありません。したがって、コレクションは実際にスレッドセーフではありません。完璧な例は、ほとんどのlinqが遅延評価され、列挙子の作成に遅延コードの実行が関係している可能性があります。 2つのスレッドで列挙しようとすると、コレクションが2回実現され、誤った結果が生成される可能性があります。

関連する問題