[C#6] 8-异常增强

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             do
12             {
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             try
22             {
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             finally
33             {
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就不做展开了,太庞大了,贴个图看下大致的情况:

2. 异常过滤器

其实这个语言特性在VB,F#里面早就支持了,现在C#6里面也可以使用了。

1 try { … }
2 catch (Exception e) when (filter(e))
3 {
4     …
5 }

其中when这一块就是异常过滤器生效的地方,when后面跟一个表达式,表达式结果如果为true,则进入当前catch语句块。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏GIS讲堂

一个GISER 6.7的祝福

一年一度的高考今天开始了,回想10年前,那是我第一次高考;10年后,作为一个GISER,在此给大家献上一个GISER的祝福,祝愿各位考生:考神附体,考完报考GI...

1504
来自专栏Create Sun

mvc+webapi 单元测试 3.使用Moq模拟AspnetMvc中的Request.Form

 1.前言     现在这个项目已经有阶段性的模块完成了,所以就想着对这些模块进行单元测试,以保证项目的代码的质量。首先虽然标题是mvc+webapi实质上我只...

6299
来自专栏草根专栏

用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(3)

由于本文主要是讲VSCode开发等, 所以相关等一些angular/.net core的知识就相对少讲点. 我把需求改一下, 如图: ? 由于efcore目前还...

3899
来自专栏草根专栏

从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD

Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-...

4146
来自专栏tkokof 的技术,小趣及杂念

Sweet Snippet 系列之 有序列表

很朴素的一种想法,为了维持 List 有序,我们可以在 Add 操作之后进行 Sort 操作(Remove 操作后不需要重新 Sort):

501
来自专栏魏琼东

一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-使用UDA操纵SQL语句

       上一篇文章基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义中对本案例所涉及的数据表及部分数据,本文开始将从最基本的业务,数...

2115
来自专栏智能大石头

老瓶装新酒 - C#调用WM手机发送短信(源码)

一些系统,需要能够发送短信,量很小,平均每日10条。 运营商平台太贵,白名单很严格,小额只能发省内; 各短信平台有各种限制,大事件前后会关闭; 飞信以前可以用W...

2455
来自专栏岑玉海

C#向excel中写入数据的三种方式

第一种:将DataGrid中的数据以流的形式写到excel中,格式以html的形式存在             Response.Clear();       ...

3214
来自专栏me的随笔

模板方法模式实践

在实际编程中,会经常遇到多个类中的某些方法实现逻辑类似的情况,这时我们可以将这些类中的相同部分抽象到父类中,对于有差异的地方,子类根据自身的实际需求来各自实现。

1052
来自专栏草根专栏

使用两种方法让 ASP.NET Core 实现遵循 HATEOAS 结构的 RESTful API

HATEOAS(Hypermedia as the engine of application state)是 REST 架构风格中最复杂的约束,也是构建成熟 ...

58011

扫码关注云+社区

领取腾讯云代金券