前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[C#6] 8-异常增强

[C#6] 8-异常增强

作者头像
blackheart
发布2018-01-19 16:40:17
6870
发布2018-01-19 16:40:17
举报
文章被收录于专栏:blackheart的专栏

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中将不再受此限制。

代码语言:javascript
复制
 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方法(非线程安全的方法)里面的两行代码被多个线程争抢调用引起的:

代码语言:javascript
复制
1 Console.ForegroundColor = color;
2 Console.WriteLine($"{message,-20} : {Thread.CurrentThread.ManagedThreadId}");

我们可以做点小改动来让Log方法做到线程安全(在C#中有很多方式可以做到,这只是其中一种):

代码语言:javascript
复制
 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里面也可以使用了。

代码语言:javascript
复制
1 try { … }
2 catch (Exception e) when (filter(e))
3 {
4     …
5 }

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-03-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0. 目录
  • 1. 在catch和finally块中使用await
  • 2. 异常过滤器
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档