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.ki4.cn/
以上就是C#非常加强 的细致内容,更多请关注ki4网别的相干文章!