次のようなものを含むクラスがあります:
public static class Config
{
private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
() => { /* "ValueFactory" here... */ },
true);
public static ConfigSource ConfigSource
{
get { return _cfgSrc.Value; }
}
}
ConfigSource
プロパティにアクセスするときに、このInvalidOperationException
に遭遇しました:
ValueFactoryがこのインスタンスのValueプロパティにアクセスしようとしました。
Value
プロパティにアクセスする「値ファクトリ」メソッドには何も表示されません。この例外を引き起こしている可能性があるものは他にありますか?この問題は断続的にのみ発生しますが、一度発生すると、IISをリセットして例外を解消します(例外は発生するとキャッシュされるようです)。
このエラーは、Visual StudioデバッガーでLazy<>
のValue
プロパティを検査しようとしたときにのみ発生することが判明しました。そうすると、Value
へのアクセスがInvalidOperationException
が最終的に発生するまでスレッドを長時間ハングさせているように見えるため、デッドロックが発生するように見えました。元のException
を傍受できなかったため、内部のスタックトレースを確認できませんでした。
私はこれをVisual StudioのバグまたはLazy<>
の実装としてチョークで示しています。
ValueFactoryがこのインスタンスのValueプロパティにアクセスしようとしました。
それは誰かを助けるかもしれません、私は私のValueFactoryプロシージャ全体を検査することによってそのエラーを修正することができました。私の例では、単純なモデルを作成して他のデータとリンクしていましたが、リンクプロセス中にシングルトンのValueプロパティにアクセスしていたため、エラーが発生しました。
つまり、ValueFactoryスロー内のLazyオブジェクトの値にアクセスするとなどエラーとなります。エラーメッセージはすでに示しているので;-)
これは循環依存関係でも発生しているため、これらの手順を実行しても何も起こらない場合は、スタックトレースを再確認して循環依存関係がないことを確認してください。
Lazy<T>
の動作は、ValueFactory
によってスローされた例外をキャッシュすることです。これは、InvalidOperationException
メッセージで提供される情報が少ないために、混乱を招く可能性のある動作につながる可能性があります。 MicrosoftはConnect を通じてこの問題を認識していましたが、Wont Fixとマークされているため、問題を診断するのに十分な情報が例外自体にあると感じてください。
受け取るIOEに内部例外がある場合は、続行するのに十分な情報が含まれているはずです(そうするわけではありません)。もう1つの可能性は、例外を再スローするtry...catch
ブロックがあることです(throw ex;
ではなくthrow;
)。貴重な情報が失われます。
例外がキャッシュされないようにするには、2番目のパラメーターとして、trueではなくLazyThreadSafetyMode.PublicationOnlyを使用します。
Trueを使用すると、LazyThreadSafetyMode.ExecutionAndPublicationになります。これにより、1つのスレッドのみがValueFactoryメソッドに入ることが保証されますが、例外がキャッシュされることも保証されます。
private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
() => { /* "ValueFactory" here... */ },
LazyThreadSafetyMode.PublicationOnly);
詳細については、提供されているリンク「sixlettervariables」を参照してください。
構成を遅延ロードするときは、その構成を必要とするメソッドを呼び出さないようにしてください。これにより、プロセスを最初からやり直す構成ローダーが呼び出され、その結果、説明されたエラーが発生します。
私の場合、ロガーが設定を必要としている間、私は負荷状態をログに記録していました