C#異常增強

來源:互聯網
上載者:User

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中所寫的代碼,被轉移到MoveNext中(更詳細的資料請移步園友"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/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.