受約束的執行區域 (CER) 是創作可靠托管代碼的機制的一部分。CER 定義一個區域,在該區域中公共語言運行庫 (CLR) 會受到約束,不能引發可使區域中的代碼無法完全執行的帶外異常。在該區域中,用戶代碼受到約束,不能執行會導致引發帶外異常的代碼。PrepareConstrainedRegions?方法必須直接位于?try塊之前,并將?catch、finally?和?fault?塊標記為受約束的執行區域。標記為受約束的區域后,代碼只能調用其他具有強可靠性約定的代碼,而且代碼不應分配或者對未準備好的或不可靠的方法進行虛調用,除非代碼已經準備好處理錯誤。CLR 為 CER 中正在執行的代碼延遲線程中止。
除批注的?try?塊外,受約束的執行區域還以其他形式用于 CLR 中,特別是在從?CriticalFinalizerObject?類派生的類中執行的關鍵終止程序和使用ExecuteCodeWithGuaranteedCleanup?方法執行的代碼。

CLR 會事先準備 CER 以避免出現內存不足的情況。進行事先準備的目的是為了避免 CLR 在實時編譯或類型加載時發生內存不足的情況。
開發人員需要指定一個代碼區域作為 CER:
-
頂級 CER 區域和完整調用關系圖中應用了?ReliabilityContractAttribute?屬性的方法是事先準備好的。ReliabilityContractAttribute?只能聲明?Success?或MayFail?的保證。
-
事先準備不能針對無法靜態確定的調用(如虛調度)執行。此時可使用?PrepareMethod?方法。使用?ExecuteCodeWithGuaranteedCleanup?方法時,應該對清理代碼應用?PrePrepareMethodAttribute?屬性。

用戶可在 CER 中寫入的代碼的類型受到限制。代碼不能導致帶外異常,例如以下操作就可能導致此類異常:
-
顯式分配。
-
裝箱。
-
獲取鎖。
-
對未準備好的方法進行虛調用。
-
調用具有弱可靠性約定或不具有可靠性約定的方法。
在 .NET Framework 2.0 版中,這些約束稱為準則。診斷通過代碼分析工具提供。

ReliabilityContractAttribute?是記錄給定方法的可靠性保證和損壞狀態的自定義屬性。
可靠性保證
可靠性保證由?Cer?枚舉值表示,指示給定方法的可靠度:
-
MayFail?。在異常情況下,該方法可能會失敗。在這種情況下,該方法會向進行調用的方法報告是成功還是失敗。該方法必須包含在 CER 中,以確保它可以報告返回值。
-
None?。該方法、類型或程序集沒有 CER 的概念,如果不從狀態損壞進行遷移,則在 CER 內進行調用很可能是不安全的。它不利用 CER 保證。這意味著:
-
在異常情況下,該方法可能會失敗。
-
該方法可能報告失敗,也可能不報告失敗。
-
最可能的情形是未編寫該方法以使用 CER。
-
如果方法、類型或程序集未顯式標識為成功的,則會隱式標識為?None。
-
-
Success?。在異常情況下,會保證該方法能夠成功。若要達到此可靠性級別,應始終在調用的方法周圍構造 CER,即使是從非 CER 區域內進行調用。如果一個方法完成了其任務,它就是成功的,雖然這種成功可能只是主觀認為的成功。例如,用?ReliabilityContractAttribute(Cer.Success)?標記 Count 意味著當它在 CER 下運行時,它始終返回?ArrayList?中元素的數目的計數,并且它永遠不能將內部字段保留為不確定狀態。 但是,CompareExchange方法也標記為成功,這里的成功意味著該值不會因爭用條件而替換為新值。 關鍵在于該方法的行為方式與記錄的行為方式相同,不需要在 CER 代碼中處理除正確但不可靠代碼的行為之外的任何非正常行為。
損壞級別
損壞級別由?Consistency?枚舉值表示,指示給定環境下狀態的損壞程度:
-
MayCorruptAppDomain?。在異常情況下,公共語言運行庫 (CLR) 對當前應用程序域中的狀態一致性不做任何保證。
-
MayCorruptInstance?。在異常情況下,該方法保證將狀態損壞限制到當前實例。
-
MayCorruptProcess?,在異常情況下,CLR 對狀態一致性不做任何保證;即這種情況可能會損壞進程。
-
WillNotCorruptState?。在異常情況下,保證該方法不會損壞狀態。

可靠性?try/catch/finally?是一種異常處理機制,其可預知性保證的級別與非托管版本相同。catch/finally?塊為 CER。塊中的方法需要事先準備,并且必須是不可中斷的。
在 .NET Framework 2.0 版中,代碼通過在 try 塊前直接調用?PrepareConstrainedRegions?來通知運行庫 try 是可靠的。PrepareConstrainedRegions?是編譯器支持類?RuntimeHelpers?的成員。通過使用編譯器暫停可用性,直接調用?PrepareConstrainedRegions。

不可中斷區域可將一組指令分組到 CER 中。
在 .NET Framework 2.0 版中,通過使用編譯器支持暫停可用性,用戶代碼創建不可中斷的區域,其中具有包含前面是?PrepareConstrainedRegions?方法調用的空 try/catch 塊的可靠 try/catch/finally。

CriticalFinalizerObject?保證垃圾回收會執行終結器。進行分配時,終結器及其調用關系圖是事先準備好的。終結器方法在 CER 中執行,并且必須服從所有有關 CER 和終結器的約束。
從?SafeHandle?和?CriticalHandle?繼承的任何類型都保證在 CER 內執行其終結器。在?SafeHandle?派生類中實現?ReleaseHandle?可執行釋放句柄所需的所有代碼。

CER 中不允許下面的操作:
-
顯式分配。
-
獲取鎖。
-
裝箱。
-
多維數組訪問。
-
通過反射進行的方法調用。
-
Enter?或?Lock。
-
安全檢查。不執行命令,僅鏈接命令。
-
COM 對象和代理的?Isinst?和?Castclass
-
獲取或設置透明代理上的字段。
-
序列化。
函數指針和委托。
-
class Program
{
static void Main()
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
Console.WriteLine("try");
}
finally
{
type.dosome();
}
Console.WriteLine();
Console.ReadKey();
}
}
class type
{
static type()
{
Console.WriteLine("ctor");
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void dosome()
{
}
}
-