日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

.NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)...

發布時間:2024/7/5 C# 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

不知你是否見過 try { } finally { } 代碼中,try 塊留空,而只往 finally 中寫代碼的情況呢?這種寫法有其特殊的目的。

本文就來說說這種不一樣的寫法。


?

本文內容

      • 空的 try 塊
      • 受約束的執行區域(Constrained Execution Regions)
        • 參考資料

?

空的 try 塊

你可以點開這個鏈接查看 Exception 類,在里面你可以看到一段異常處理的代碼非常奇怪:

// 代碼已經過簡化。 internal void RestoreExceptionDispatchInfo(ExceptionDispatchInfo exceptionDispatchInfo) {// 省略代碼。try{}finally{// 省略代碼。}// 省略代碼。 }

神奇之處就在于,其 try 塊是空的,重要代碼都放在 finally 中。那為什么會這么寫呢?

在代碼注釋中的解釋為:

We do this inside a finally clause to ensure ThreadAbort cannot be injected while we have taken the lock. This is to prevent unrelated exception restorations from getting blocked due to TAE.

翻譯過來是:

在 finally 子句中執行此操作以確保在獲取鎖時無法注入 ThreadAbort。這是為了防止不相關的異常恢復因 TAE 而被阻止。

也就是說,此方法是為了與 Thread.Abort 對抗,防止 Thread.Abort 中斷此處代碼的執行。 Thread.Abort 的執行交給 CLR 管理,finally 的執行也是交給 CLR 管理。CLR 確保 finally 塊執行的時候不會被 Thread.Abort 阻止。

代碼在 .NET Core 和 .NET Framework 中的實現完全一樣:

// This is invoked by ExceptionDispatchInfo.Throw to restore the exception stack trace, corresponding to the original throw of the // exception, just before the exception is "rethrown". [SecuritySafeCritical] internal void RestoreExceptionDispatchInfo(System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo) {bool fCanProcessException = !(IsImmutableAgileException(this));// Restore only for non-preallocated exceptionsif (fCanProcessException){// Take a lock to ensure only one thread can restore the details// at a time against this exception object that could have// multiple ExceptionDispatchInfo instances associated with it.//// We do this inside a finally clause to ensure ThreadAbort cannot// be injected while we have taken the lock. This is to prevent// unrelated exception restorations from getting blocked due to TAE.try{}finally{// When restoring back the fields, we again create a copy and set reference to them// in the exception object. This will ensure that when this exception is thrown and these// fields are modified, then EDI's references remain intact.//// Since deep copying can throw on OOM, try to get the copies// outside the lock.object _stackTraceCopy = (exceptionDispatchInfo.BinaryStackTraceArray == null)?null:DeepCopyStackTrace(exceptionDispatchInfo.BinaryStackTraceArray);object _dynamicMethodsCopy = (exceptionDispatchInfo.DynamicMethodArray == null)?null:DeepCopyDynamicMethods(exceptionDispatchInfo.DynamicMethodArray);// Finally, restore the information. //// Since EDI can be created at various points during exception dispatch (e.g. at various frames on the stack) for the same exception instance,// they can have different data to be restored. Thus, to ensure atomicity of restoration from each EDI, perform the restore under a lock.lock(Exception.s_EDILock){_watsonBuckets = exceptionDispatchInfo.WatsonBuckets;_ipForWatsonBuckets = exceptionDispatchInfo.IPForWatsonBuckets;_remoteStackTraceString = exceptionDispatchInfo.RemoteStackTrace;SaveStackTracesFromDeepCopy(this, _stackTraceCopy, _dynamicMethodsCopy);}_stackTraceString = null;// Marks the TES state to indicate we have restored foreign exception// dispatch information.Exception.PrepareForForeignExceptionRaise();}} }

你可以在 這里 查看 .NET Framework 版本,在這里 查看 .NET Core 的版本。

受約束的執行區域(Constrained Execution Regions)

這種現象在微軟官方文檔 可靠性最佳做法 中有介紹。

Doing so instructs the just-in-time compiler to prepare all the code in the finally block before running the try block. This guarantees that the code in the finally block is built and will run in all cases. It is not uncommon in a CER to have an empty try block. Using a CER protects against asynchronous thread aborts and out-of-memory exceptions. See ExecuteCodeWithGuaranteedCleanup for a form of a CER that additionally handles stack overflows for exceedingly deep code.

使用 try-finally 形成一個受約束的執行區域,使得 finally 中的代碼被可靠地執行。


參考資料

  • 可靠性最佳做法 - Microsoft Docs
  • 受約束的執行區域 - Microsoft Docs
  • exception.cs - Reference Source
  • RestoreExceptionDispatchInfo
  • The empty try block mystery - Some Creativity
  • c# - Why use try {} finally {} with an empty try block? - Stack Overflow
  • corefx/System.Runtime.cs at master · dotnet/corefx

轉載于:https://www.cnblogs.com/walterlv/p/10236401.html

總結

以上是生活随笔為你收集整理的.NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。