本文摘自PHP中文网,作者PHPzhong,侵删。
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 | 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 | 1 Console.ForegroundColor = color;2 Console.WriteLine($ "{message,-20} : {Thread.CurrentThread.ManagedThreadId}" );
|
我们可以做点小改动来让Log方法做到线程安全(在C#中有很多方式可以做到,这只是其中一种):
1 | 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 | 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#异常增强 的详细内容!
相关阅读 >>
C# 带滚动条的label控件的示例代码详解
【C#教程】C# 多态性
C#如何导入导出与处理excel文件
C# web应用调试开启外部访问的步骤
C# 使用npoi生成word文档(按照模板)
详解C#使用xsd文件验证xml格式是否正确的实现方法
C#-json详解
简单记录C# 条件编译(图文详解)
详细介绍5个最优秀的java和C#代码转换工具(图)
C#计算标准偏差相当于excel中的stdev函数的代码案例
更多相关阅读请进入《C#》频道 >>
清华大学出版社
作者:[美]克里斯琴·内格尔(Christian Nagel)著。出版时间:2019年3月。
转载请注明出处:木庄网络博客 » C#异常增强