制約付き実行領域 (CER) は、信頼性の高いマネージド コードを作成するためのメカニズムの一部です。 CER は、共通言語ランタイム (CLR) が帯域外例外をスローすることを制限する領域を定義します。これにより、領域内のコード全体が実行されなくなります。 その領域内では、ユーザー コードは、帯域外の例外がスローされることになるコードの実行を制約されます。
PrepareConstrainedRegions メソッドは、try
ブロックの直前に置き、catch
、finally
、およびfault
ブロックを制約のある実行領域としてマークする必要があります。 制約付き領域としてマークされると、コードは信頼性の高いコントラクトを持つ他のコードのみを呼び出す必要があります。また、コードでエラーを処理する準備が整っていない限り、準備されていないメソッドや信頼性の低いメソッドに対して仮想呼び出しを割り当てたり行ったりしないでください。 CLR は、CER で実行されているコードのスレッドの中止を遅延させます。
Von Bedeutung
CER は.NET Framework でのみサポートされています。 この記事は、.NET Core または .NET 5 以降には適用されません。
制約付き実行領域は、注釈付き try
ブロックに加えて、CLR のさまざまな形式で使用されます。特に、 CriticalFinalizerObject クラスから派生したクラスで実行される重要なファイナライザーと、 ExecuteCodeWithGuaranteedCleanup メソッドを使用して実行されるコードです。
CER の事前準備
CLR は、メモリ不足の状態を回避するために、事前に CER を準備します。 CLR がジャストインタイムコンパイルまたは型の読み込み中にメモリ不足状態を引き起こさないように、事前の準備が必要です。
開発者は、コード領域が CER であることを示す必要があります。
ReliabilityContractAttribute属性が適用されている完全な呼び出しグラフの最上位レベルの CER 領域とメソッドは、事前に準備されています。 ReliabilityContractAttributeは、SuccessまたはMayFailの保証を述べることのみができます。
仮想ディスパッチなど、静的に決定できない呼び出しに対して事前準備を実行することはできません。 このような場合は、 PrepareMethod メソッドを使用します。 ExecuteCodeWithGuaranteedCleanup メソッドを使用する場合は、PrePrepareMethodAttribute属性をクリーンアップ コードに適用する必要があります。
制約
ユーザーは、CER で記述できるコードの種類に制約があります。 このコードでは、次の操作の結果として発生する可能性がある、帯域外例外を発生させることはできません。
明示的な割り当て。
ボクシング。
ロックの取得。
準備されていないメソッドを仮想的に呼び出す。
弱い、または存在しない信頼性コントラクトを持つメソッドを呼び出します。
.NET Framework バージョン 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
信頼性 try/catch/finally
は、アンマネージド バージョンと同じレベルの予測可能性保証を持つ例外処理メカニズムです。
catch/finally
ブロックは CER です。 ブロック内のメソッドには事前の準備が必要であり、中断できません。
.NET Framework バージョン 2.0 では、try ブロックの直前に PrepareConstrainedRegions を呼び出すことで、try が信頼できるかどうかをランタイムに通知します。 PrepareConstrainedRegions は、コンパイラ サポート クラスである RuntimeHelpers のメンバーです。 コンパイラで使用できるようになるまで PrepareConstrainedRegions を直接呼び出します。
非中断リージョン
中断できないリージョンでは、一連の命令が CER にグループ化されます。
.NET Framework バージョン 2.0 では、コンパイラのサポートによって可用性が保留中のユーザー コードによって、信頼できる try/catch/finally を使用して中断できないリージョンが作成されます。このリージョンには、 PrepareConstrainedRegions メソッド呼び出しの前に空の try/catch ブロックが含まれています。
クリティカル ファイナライザー オブジェクト
CriticalFinalizerObject は、ガベージ コレクションでファイナライザーが実行されることを保証します。 割り当て時に、ファイナライザーとその呼び出しグラフが事前に準備されます。 ファイナライザー メソッドは CER で実行され、CER とファイナライザーのすべての制約に従う必要があります。
SafeHandleおよびCriticalHandleから継承するすべての型は、CER 内でファイナライザーを実行することが保証されます。 ReleaseHandle派生クラスにSafeHandleを実装して、ハンドルを解放するために必要なコードを実行します。
CER でコードが許可されない
CER では、次の操作は許可されません。
明示的な割り当て。
ロックの取得。
ボクシング。
多次元配列アクセス。
リフレクションを通じたメソッド呼び出し。
セキュリティ チェック。 要求を実行せず、要求をリンクするだけです。
透明プロキシでフィールドを取得または設定する。
シリアライゼーション
関数ポインターとデリゲート。
こちらも参照ください
.NET