限制執行區域 (CER) 是撰寫可靠 Managed 程式代碼的機制的一部分。 CER 會定義一個區域,其中 Common Language Runtime (CLR) 會限制擲回頻外例外狀況,以防止區域中的程式碼完全執行。 在該區域內,用戶程式代碼被限制執行引發帶外异常的代码。 方法PrepareConstrainedRegions必須緊接在 try 區塊前面,並將、 catch和 finally 區塊標示fault為限制的執行區域。 標示為限制區域之後,程式代碼只能呼叫具有強可靠性合約的其他程式碼,而且程式代碼不應配置或對未準備或不可靠的方法進行虛擬呼叫,除非程式代碼已準備好處理失敗。 CLR 會延遲在 CER 中執行之程式代碼的線程中止。
這很重要
只有 .NET Framework 才支援 CER。 本文不適用於 .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 區域內呼叫它也一樣。 如果一個方法達成了預期的目標,那麼這個方法就是成功的,但成功的定義可以是主觀的。 例如,使用
ReliabilityContractAttribute(Cer.Success)標記 Count 表示在 CER 下執行時,它一律會傳回 中 ArrayList 元素數目的計數,而且永遠不能讓內部欄位處於未決定的狀態。 不過,方法 CompareExchange 也會標示為成功,因為成功可能意味著由於競爭條件,無法用新值替換舊值。 關鍵在於方法的行為必須嚴格按照其文件中的描述運作,而且 CER 程式碼不需要撰寫來應對任何不超出正確但不可靠的程式碼預期之外的不尋常行為。
貪腐程度
由列舉值 Consistency 代表的腐敗等級指出在特定環境中可能有多少狀態遭到損毀。
MayCorruptAppDomain。 在特殊情況下,Common Language Runtime (CLR) 不會保證目前應用程式域中的狀態一致性。
MayCorruptInstance。 在特殊情況下,該方法保證將狀態損毀限制在當前的實例。
MayCorruptProcess在特殊情況下,CLR 不會保證狀態一致性:也就是說,條件可能會損毀進程。
WillNotCorruptState。 在特殊情況下,方法保證不會損毀狀態。
可靠度 try/catch/finally
可靠性try/catch/finally是例外處理機制,其可預測性保證層級與Unmanaged版本相同。 區塊 catch/finally 是 CER。 區塊中的方法需要預先準備,而且必須不可中斷。
在 .NET Framework 2.0 版中,程式碼會藉由在 try 區塊之前立即呼叫 PrepareConstrainedRegions,通知執行時該 try 區塊是可靠的。 PrepareConstrainedRegions 是編譯器支持類別 RuntimeHelpers 的成員。 在編譯器可用之前直接呼叫 PrepareConstrainedRegions。
不可中斷的區域
不可中斷的區域會將一組指示分組到 CER 中。
在 .NET Framework 2.0 版中,由於編譯器的支援正在推向普及,用戶程式碼可以使用可靠的 try/catch/finally 來建立不可中斷的程式區域,其中包含在方法呼叫之前的空 try/catch 區塊。
重要完成項物件
保證 CriticalFinalizerObject 垃圾收集會執行終結器。 在分配時,終結器及其呼叫圖會預先準備。 終結器方法會在 CER 中執行,而且必須遵守 CER 和終結器的所有條件約束。
繼承自 SafeHandle 和 CriticalHandle 的任何型別,保證其終結器會在 CER 內執行。 在ReleaseHandle衍生類別中實作SafeHandle以執行任何釋放句柄所需的程式碼。
CER 中不允許的程序代碼
CER 中不允許下列作業:
明確配置。
取得鎖。
拳擊。
多維度陣列存取。
透過反射進行方法呼叫。
安全檢查。 不要執行需求,只連結需求。
取得或設定透明代理上的欄位。
序列化。
函式指標和委派。