// Member Variable
private static readonly object _syncLock = new object();
// Now inside a static method
foreach (var lazyObject in plugins)
{
if ((string)lazyObject.Metadata["key"] = "something")
{
lock (_syncLock)
{
// It seems the `IsValueCreated` is not up-to-date
if (!lazyObject.IsValueCreated)
lazyObject.value.DoSomething();
}
return lazyObject.value;
}
}
ループごとに同期アクセスが必要です。このループを反復する多くのスレッドがあり、それらが探しているkey
に基づいて、遅延インスタンスが作成されて戻されます。MEFを使用したスレッドセーフな遅延インスタンス化
lazyObject
を1回以上作成しないでください。 Lazy
クラスは、ロックを使用しているにもかかわらず、ハイスレッディングの下で複数のインスタンスが作成されています(これはvolatile
static int
のInterlocked.Increment
で追跡し、どこかにログします)。問題は私がLazy
の定義へのアクセス権を持っていないこととMEF
がLazy
クラスがどのようにオブジェクトを作成するかを定義していることです。 CompositionContainer
には、すでに使用されているコンストラクタ内のスレッドセーフなオプションがあることに気付くはずです。
私の質問:
1)なぜロックが機能しないのですか?
2)パフォーマンス向上のために、ロックの代わりにロックの配列を使用する必要がありますか?
...
if
声明のタイプミスました。あなたは静的メンバー関数(コンパイルされません)によってアクセスされるクラスの非静的メンバー変数を持っています –もちろん静的です。編集されました。 – Xaqron
'return lazyObject.value'をロック内に移動しようとします。 – jgauffin