首頁  >  文章  >  後端開發  >  C#異常增強

C#異常增強

PHPz
PHPz原創
2017-03-12 15:45:501181瀏覽

0. 目錄

C#6 新增特性目錄

1. 在catch和finally區塊中使用await

在C#5中引入一對關鍵字await/async,用來支援新的非同步編程模型,使的C#的非同步編程模型進一步的簡化(APM->EAP->TAP->await/async,關於C#中的非同步程式設計模型的不是本篇文章的介紹重點,詳細的資料請移步這裡Asynchronous Programming Pattern)。在C#5中雖然引入了await/async,但是卻有一些限制,例如不能再catch和finally語句區塊中使用,C#6中將不再受此限制。


 1 using System; 2 using System.Threading; 3 using System.Threading.Tasks; 4  5 namespace csharp6 6 { 7     internal class Program 8     { 9         private static void Main(string[] args)10         {11             do12             {13                 Log(ConsoleColor.White, "caller method begin", true);14                 CallerMethod();15                 Log(ConsoleColor.White, "caller method end");16             } while (Console.ReadKey().Key != ConsoleKey.Q);17         }18 19         public static async void CallerMethod()20         {21             try22             {23                 Log(ConsoleColor.Yellow, "try ", true);24                 throw new Exception();25             }26             catch (Exception)27             {28                 Log(ConsoleColor.Red, "catch await begin", true);29                 await AsyncMethod();30                 Log(ConsoleColor.Red, "catch await end");31             }32             finally33             {34                 Log(ConsoleColor.Blue, "finally await begin", true);35                 await AsyncMethod();36                 Log(ConsoleColor.Blue, "finally await end");37             }38         }39 40         private static Task AsyncMethod()41         {42             return Task.Factory.StartNew(() =>43             {44                 Log(ConsoleColor.Green, "async method begin");45                 Thread.Sleep(1000);46                 Log(ConsoleColor.Green, "async method end");47             });48         }49 50         private static void Log(ConsoleColor color, string message, bool newLine = false)51         {52             if (newLine)53             {54                 Console.WriteLine();55             }56             Console.ForegroundColor = color;57             Console.WriteLine($"{message,-20} : {Thread.CurrentThread.ManagedThreadId}");58         }59     }60 }

運行結果如下:

如果你細心的話會發現async method begin:6這一行的顏色居然不是我設定的綠色,而是白色,而且順序也出現了錯亂;而你再運行一次,它可能就是綠色了。這其實是由於我在Log方法(非執行緒安全的方法)裡面的兩行程式碼被多個執行緒爭搶呼叫所引起的:


##

1 Console.ForegroundColor = color;2 Console.WriteLine($"{message,-20} : {Thread.CurrentThread.ManagedThreadId}");
我們可以做點小改動來讓Log方法做到執行緒安全性(在C#中有很多方式可以做到,這只是其中一種):


 1 [MethodImpl(MethodImplOptions.Synchronized)] 2 private static void Log(ConsoleColor color, string message, bool newLine = false) 3 { 4     if (newLine) 5     { 6         Console.WriteLine(); 7     } 8     Console.ForegroundColor = color; 9     Console.WriteLine($"{message,-20} : {Thread.CurrentThread.ManagedThreadId}");10 }
看起來有點離題了,回歸正題,在catch和finally語句塊中支持await關鍵字並不需要IL指令的支持,也不需要CLR的支持,而僅僅是編譯器做出的代碼轉換(await/async就像lambda一樣到delegate一樣)。具體的IL就不做展開了,太龐大了,貼圖看下大致的情況:

#我們在CallerMethod中所寫的程式碼,被轉移到Move

Next中(更詳細的資料請移步園友"Dev_Eric"的一篇部落格:進階篇:以IL為劍,直指async/await)(包含catch和finally中的await語句)。

2. 異常

濾鏡

其實這個語言特性在VB,F#裡面早就支援了,現在C#6裡面也可以使用了。


1 try { … }2 catch (Exception e) when (filter(e))3 {4     …5 }
其中when這一塊就是異常過濾器生效的地方,when後面跟一個

表達式,表達式結果如果為true,則進入當前catch語句塊。

3. 參考

Asynchronous Programming Patterns

C# 6.0 await in catch/finally

##C# 6.0 Exception filters

http:/ /www.php.cn/

以上是C#異常增強的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn