任务类在.NET4.5中的一些改进

  

任务类在.NET4.5中,做了一些改进,比如新增了方法使用ConfigureAwait,延迟,运行等方法。其中一个重要修改,就是对于异常的处理。

在.NET4.0中,任务中抛出的异常,如果没有去捕获,在任务被垃圾回收的时候,析构函数检测到该任务对象还有未被处理过的异常,会抛出这个异常,并且导致进程终结,进程终结的时间是由垃圾回收器和析构方法决定的。(可以通过注册TaskSchedular.UnobservedTaskException事件处理未捕获的异常)。

在.NET4.5中,微软改变了策略,对于任务中未处理的异常,默认情况下不会导致杀死进程。这个可以通过配置ThrowUnobservedTaskExceptions节点实现。

默认情况下,ThrowUnobservedTaskExceptions这个节点的启用=false。如下配置。

 & lt; configuration>
  ,,,& lt; runtime>
  ,,,,,& lt; ThrowUnobservedTaskExceptions 启用=癴alse”/比;
  ,,,& lt;/runtime>
  & lt;/configuration> 

这种情况下,在.NET4.5中,GC回收对象的时候,是不会导致程序崩溃的,未捕获的异常就这样消失了。比如下面的代码:

static  void  Main (string [], args)   {   ,,,,,for  (int 小姐:=,0;,小姐:& lt;, 10;,我+ +)   ,,,,,{   ,,,,,,,,,,var  t =, Task.Factory.StartNew((),=祝辞,{,throw  new 例外(xxxxxx);, return  1;,}   ,,,,,,,,,,,,,,,,,,,,,,,,,,,CancellationToken.None TaskCreationOptions.None,, TaskScheduler.Default);   ,,,,,,,,,,,}   ,,,,,while (真正的)   ,,,,{   ,,,,,,,,,,GC.Collect ();   ,,,,,,,,,,thread . sleep (1000);   ,,,,,}   ,,,,,Console.ReadKey ();   }

但是如果设置& lt; ThrowUnobservedTaskExceptions启用=" true "/祝辞,那么程序就会崩溃,这和在.NET4.0中的结局一样。

叭挝窭嘣?NET4.5中的一些改进"

叭挝窭嘣?NET4.5中的一些改进"

当然,对于所有的异常,都是建议捕获并且处理的. . NET4.0和4.5都提供了TaskScheduler。UnobservedTaskException事件,通过监听这个事件,也可以捕获到这个异常。

代码如下:

TaskScheduler.UnobservedTaskException  +=,(啊,,ev),=比;   {   ,,,,,Console.WriteLine (ev.Exception);   ,,,,,ev.SetObserved ();   ,,,,,Console.WriteLine (“- - - - - - - - - - - -”);   };

注意:<强> ev.SetObserved();方法必须要调用,这样才能阻止进程崩溃。

,

<强>

还有一处改进是对于异常的捕获上。对于任务中抛出的异常,外部的尝试捕捉是无法捕获的,例如:

static  Task, f ()   {   试一试   {   var 才能;t =, Task.Factory.StartNew((),=祝辞,{,throw  new 例外(xxxxxx);, return  1;,});   return 才能;t;   }   抓   {   Console.WriteLine才能(“错误”);   }   return 零;   }

无论是在.net4.0还是.net4.5,上述代码都是不会走到抓中的。只有当运行Task.Wait或者读取Task.Result的时候(这些方法都会引起阻塞),才会抛出异常,由于运行的任务可能是包含了多个子任务,或者在WaitAll多个任务,那么异常可能会出现多个.Task类会把这些异常包成AggregateException异常。要获得异常的正真信息,需要访问AggregateException.InnerExceptions属性。如下代码:

Task, t1 =, Task.Factory.StartNew((),=比;   {才能   ,,throw  new 例外(“error1”);   ,,});   Task((),=比;   {   throw  new 例外(“error2”);   });   Task((),=比;   {   throw  new 例外(“error3”);   });   试一试   {   Task.WaitAll (t1、t2、t3);   }   catch  (AggregateException 交货)   {   Console.WriteLine (“Exception 类型:{0},ex.GetType ());   Console.WriteLine (“Exception 信息:{0},ex.Message);   Console.WriteLine (“Exception 加:{0},ex.StackTrace);   Console.WriteLine (“Exception  InnerException.Message: {0}, ex.InnerException.Message);   foreach  (var  innerEx  ex.InnerExceptions拷贝)   {   Console.WriteLine才能(“InnerExceptions.Message: {0}, innerEx.Message);   }   }

任务。null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

任务类在.NET4.5中的一些改进