更新 : 2007 年 11 月
制約された実行領域 (CER: Constrained Execution Region) は、信頼性のあるマネージ コードを作成するための機構の一部です。CER は、領域内のコードが領域全体で実行されるのを防ぐ帯域外の例外を、共通言語ランタイム (CLR: Common Language Runtime) がスローすることを制約された領域を定義します。その領域内では、ユーザー コードは、帯域外の例外がスローされることになるコードの実行を制約されます。PrepareConstrainedRegions メソッドは、try ブロックの直前に呼び出す必要があります。このメソッドによって、catch、finally、fault の各ブロックが制約された実行領域としてマークされます。制約された領域としてマークされると、コードは信頼性の高いコントラクトでのみ他のコードを呼び出す必要があります。また、コードがエラーを処理できるようになるまで、コードは準備されていないメソッドや信頼性のないメソッドの割り当てや仮想呼び出しを行うことはできません。CLR は、CER で実行しているコードに対してスレッドの中止を遅らせます。
制約された実行領域は、注釈付きの try ブロックだけでなく、特に CriticalFinalizerObject クラスから派生したクラス、および ExecuteCodeWithGuaranteedCleanup メソッドを使用して実行されるコードで実行する重大なファイナライザなど、CLR のさまざまな形式で使用されます。
CLR は、メモリ不足の状態を回避するために、CER を事前に準備します。JIT (Just-In-Time) コンパイル時や型の読み込み時に、CLR がメモリ不足の状態を引き起こさないように、事前準備が必要となります。
次のように、開発者はコード領域が CER であることを示す必要があります。
ReliabilityContractAttribute 属性が適用されたすべての呼び出し先のトップレベルの CER 領域とメソッドは事前に準備されます。ReliabilityContractAttribute は、Success または MayFail の保証だけを示すことができます。
仮想ディスパッチなど、静的に決定できない呼び出しに対して事前準備を行うことはできません。このような場合には、PrepareMethod メソッドを使用します。ExecuteCodeWithGuaranteedCleanup メソッドを使用する場合は、PrePrepareMethodAttribute 属性をクリーンアップ コードに適用する必要があります。
ユーザーは、CER で書き込むことのできるコードの種類で制約を受けます。コードでは、次の操作によって生じる可能性のある帯域外の例外を発生させることはできません。
明示的な割り当て
ボックス化
ロックの取得
準備されていないメソッドの仮想呼び出し
信頼性の低いコントラクトまたは信頼性のないコントラクトでのメソッド呼び出し
.NET Framework Version 2.0 では、これらの制約はガイドラインです。診断はコード分析ツールを通じて提供されます。
ReliabilityContractAttribute は、信頼性の保証と特定のメソッドの破損状態を定義するカスタム属性です。
Cer 列挙値によって表される信頼性の保証は、特定のメソッドの信頼度を次のように示します。
MayFail。例外条件に基づき、メソッドは失敗する可能性があります。この場合、メソッドは呼び出し元のメソッドに成功したか失敗したかを報告します。メソッドが戻り値を確実に報告できるように、メソッドは CER に含まれている必要があります。
None。メソッド、型、またはアセンブリには CER の概念がないため、状態の破損を大幅に軽減しなければ、CER 内での呼び出しが安全ではない可能性が非常に高くなります。この値は、CER の保証を利用しません。これは以下を意味します。
例外条件に基づき、メソッドは失敗する可能性があります。
メソッドは、失敗したことを報告する場合もあれば、報告しない場合もあります。
メソッドは、CER の最も可能性の高いシナリオを使用するように作成されるわけではありません。
メソッド、型、またはアセンブリが成功することが明示的に識別されていない場合、暗黙的に None として識別されます。
Success。例外条件に基づき、メソッドは成功することが保証されます。このレベルの信頼性を実現するには、メソッドが CER 以外の領域内から呼び出される場合でも、呼び出されるメソッドの周辺に CER を常に構築する必要があります。成功の判断は主観的なものですが、メソッドが意図したとおりに実行された場合、そのメソッドは成功です。たとえば、Count を ReliabilityContractAttribute(Cer.Success) でマークした場合、CER での実行時に、このメソッドが ArrayList の要素数を必ず返し、内部フィールドを未確認の状態のままにすることはできないことを意味します。CompareExchange メソッドも同様に成功としてマークされますが、この成功は、競合状態によって値を新しい値に置き換えることができなかったことを意味する場合があります。重要な点は、メソッドは定義されたとおりに動作すること、そして、正しいにもかかわらず信頼性のないコードの外見以上の異常な動作を予測して CER コードを記述する必要はないということです。
Consistency 列挙値によって表される破損レベルは、特定の環境で状態がどの程度破損する可能性があるかを示します。
MayCorruptAppDomain。例外条件に基づき、共通言語ランタイム (CLR) は、現在のアプリケーション ドメインにおける状態の一貫性に関して一切保証しません。
MayCorruptInstance。例外条件に基づき、メソッドは状態の破損を現在のインスタンスに限定することが保証されます。
MayCorruptProcess。例外条件に基づき、CLR は状態の一貫性に関して一切保証しません。つまり、状況によってプロセスが破損する可能性があります。
WillNotCorruptState。例外条件に基づき、メソッドは状態を破損しないことが保証されます。
信頼性の try/catch/finally は、予測可能性の保証がアンマネージ バージョンと同じレベルである例外処理機構です。catch/finally ブロックは CER です。ブロック内のメソッドには事前準備が必要であり、中断不可能であることが必要です。
.NET Framework Version 2.0 では、コードは、try ブロックの直前に PrepareConstrainedRegions を呼び出すことにより、try が信頼できることをランタイムに通知します。PrepareConstrainedRegions は、コンパイラ サポート クラスである RuntimeHelpers のメンバです。コンパイラによって可用性が保留になっている PrepareConstrainedRegions を直接呼び出します。
中断不可能な領域は、一連の命令を CER にグループ化します。
.NET Framework Version 2.0 では、コンパイラによって可用性の保留がサポートされているため、ユーザー コードは、空の try/catch ブロックの前に PrepareConstrainedRegions メソッド呼び出しを含む信頼性のある try/catch/finally を使用して、中断不可能な領域を作成します。
CriticalFinalizerObject は、ガベージ コレクションがファイナライザを実行することを保証します。割り当て時に、ファイナライザとその呼び出し先は事前に準備されます。ファイナライザ メソッドは CER で実行されるため、CER とファイナライザのすべての制約に従う必要があります。
SafeHandle および CriticalHandle から継承するすべての型は、CER 内でファイナライザが実行されることが保証されます。SafeHandle の派生クラスで ReleaseHandle を実装して、ハンドルを解放する必要のあるコードを実行します。
CER では、次の操作は許可されません。
明示的な割り当て。
ロックの取得。
ボックス化。
多次元配列アクセス。
リフレクションを通じたメソッド呼び出し。
Enter または Lock。
セキュリティ チェック。要求 (リンク要求のみ) を実行しないでください。
COM オブジェクトおよびプロキシの Isinst と Castclass。
透過プロキシでのフィールドの取得または設定。
シリアル化。
関数ポインタとデリゲート。