4

初期化中にLazy<T>クラスとマーキングを使用することの意味は何ですか?isThreadSafe: false

レイジーがクラスコンストラクター内で初期化される静的メンバーではなくインスタンスメンバーにアクセスする必要があるシナリオでは、これisThreadSafe: false はすべての使用法で自動的に必要ですか?

4

2 に答える 2

5

レイジーがクラスコンストラクター内で初期化される静的メンバーではなくインスタンスメンバーにアクセスする必要があるシナリオでは、これは自動的に isThreadSafe: false をすべての使用法で必要としますか?

いいえ -isThreadSafe引数は、 内の値の作成方法にのみ影響しますLazy<T>

基本的に、false に設定すると、値を作成するメソッドは、値を作成し、内部ストレージに設定して、値を返すだけです。

true に設定すると、作成は の内部にラップされ、lock複数のスレッドがオブジェクトを作成するのを防ぎます。これはLazyThreadSafetyMode.ExecutionAndPublicationにマップされます。

PublicationOnly複数の値を作成できるように明示的に指定することもできますが、ロックの代わりにInterlocked.CompareExchangeを内部的に使用して、最初に完了した作成ルーチンの値がオブジェクトに使用されるものであることを確認します。

これらのオプションは、値の計算に使用されるメンバーにはまったく影響しないことに注意してください。値自体の作成方法にのみ影響します。作成以外のすべてのアクセスは、常にスレッドセーフです。Lazy<T> クラス コンストラクター内でインスタンス メンバーを初期化する場合は、同期が不要であることを効果的に保証しているため、false に設定できますが、この状況でisThreadSafe使用する理由がまったくないことも意味します。Lazy<T>明示的なインスタンス化を使用しているため...

于 2012-03-26T17:41:13.437 に答える
2

MSDNから:

一部のLazy<T>コンストラクターには、プロパティが複数のスレッドからアクセスされるかどうかを指定するために使用されるBooleanという名前のパラメーターがあります。1 つのスレッドからのみプロパティにアクセスする場合は、パスを渡してパフォーマンスをわずかに向上させます。複数のスレッドからプロパティにアクセスする場合は、インスタンスに渡して、初期化時に 1 つのスレッドが例外をスローする競合状態を正しく処理するように指示します。isThreadSafeValuefalsetrueLazy<T>

あなたが書いた...

レイジーがクラスコンストラクター内で初期化される静的メンバーではなくインスタンスメンバーにアクセスする必要があるシナリオでは、これは自動的に isThreadSafe: false をすべての使用法で必要としますか?

いいえ、インスタンスと静的とは関係ありません。遅延初期化される値が複数のスレッドでアクセスされるかどうかに関係しています。複数のスレッドでアクセスする場合は、競合状態を処理するtrueように使用してください。Lazy<T>そうでない場合は、ロックの取得falseを回避するように使用します。これにより、Lazy<T>ほとんど目立たないほどわずかなパフォーマンスの向上が得られます (競合していないロックの取得は非常に高速です)。

于 2012-03-26T17:41:16.317 に答える