多核时代 .NET Framework 4 中的并行编程4---异常处理

任何程序都避免异常情况发生.那么如何在发生异常情况时,很好的处理掉异常,以便是我们的程序继续良好的运行呢?那么介绍几种处理.Net中并行编程处理异常的几种方式.

方法1: AggregateException

表示在应用程序执行期间发生的一个或多个错误.

当使用某个静态或实例任务类Task的Wait(),WaitAll(),WaitAny()方法和Result属性时,会传播异常,您可通过将调用包括在 try-catch 语句中来处理这些异常。 如果任务是所附加子任务的父级,或者您在等待多个任务,则可能会引发多个异常。 为了将所有异常传播回调用线程,任务基础结构会将这些异常包装在 AggregateException 实例中。 AggregateException 具有一个 InnerExceptions 属性,可枚举该属性来检查引发的所有原始异常,并单独处理(或不处理)每个异常。 即使只引发了一个异常,也仍会将该异常包装在 AggregateException 中。例子如下:

        static void DealException()

        {

 

 

            Task task1 = new Task(() =>

            {

 

                throw new NotImplementedException("没有实现");

            });

 

            Task task2 = new Task(() =>

            {

                throw new ArgumentNullException("参数空");

           });

 

            Task task3 = new Task(() =>

            {

                throw new Exception("异常");

 

            });

 

            Task task4 = new Task(() =>

            {

                Console.WriteLine("正常");

 

            });

 

 

            task1.Start();

            task2.Start();

            task3.Start();

            task4.Start();

 

            try

            {

                Task.WaitAll(task1, task2, task3, task4);

           }

            catch (AggregateException agex)

            {

 

                foreach (var ex in agex.InnerExceptions)

                {

                    Console.WriteLine("异常内容是:{0}", ex.Message);

                }

              });

            }

通过代码,我们可以看到,我们只需要使用try{ …}catch()来捕获AggregateException异常,然后去处理其包含的异常即可.

方法2: AggregateException的Handle来处理每个异常.

AggregateException类型提供了一个Handle调用处理程序,以便我们对每个任务异常进行处理.代码如下:

static void DealException()

        {

          

           Task task1 = new Task(() =>

            {

 

                throw new NotImplementedException("没有实现");

            });

 

            Task task2 = new Task(() =>

            {

                throw new ArgumentNullException("参数空");

           });

 

            Task task3 = new Task(() =>

            {

                throw new Exception("异常");

 

            });

 

            Task task4 = new Task(() =>

            {

                Console.WriteLine("正常");

 

            });

 

 

            task1.Start();

            task2.Start();

            task3.Start();

            task4.Start();

            try

            {

                Task.WaitAll(task1, task2, task3, task4);

           }

            catch (AggregateException agex)

            {

 

                agex.Flatten().Handle((ex) =>

                {

 

                    if (ex is NotImplementedException)

                    {

                        Console.WriteLine("忽略");

                        return true;

                    }

                    else

                    {

                        Console.WriteLine("异常内容是:{0},已处理", ex.Message);

                        return true;

                    }

                 });

 

             

            }

            Console.ReadLine();

        }

上面代码中,捕获到异常,通过AggregateException异常实例的Flatten() 方法移除所有嵌套的 AggregateExceptions。处理程序返回true表示异常被处理。返回false则表示异常未被处理。

方法3:TaskScheduler.UnobservedTaskException 事件

当出错的 Task 的未观察到的异常将要触发异常升级策略时发生,默认情况下,这将终止进程。它提供了最后一种手段处理所有未处理异常。通过处理这个事件,就不用终止应用程序,而用你自己的异常处理逻辑替代它。代码如下:

   TaskScheduler.UnobservedTaskException +=

 (object sender, UnobservedTaskExceptionEventArgs eventArgs) =>

 {

     eventArgs.SetObserved();

   

    eventArgs.Exception.Flatten().Handle(ex =>

     {

       

         Console.WriteLine("异常是:{0}", ex.Message);

         return true;

     });

 };

           

            Task task1 = new Task(() =>

            {

                throw new NullReferenceException();

            });

            Task task2 = new Task(() =>

            {

                throw new ArgumentOutOfRangeException();

            });

            

task1.Start(); task2.Start();

          

            while (!task1.IsCompleted || !task2.IsCompleted)

            {

                Thread.Sleep(500);

            }

          

  

            Console.ReadLine();

        }

好,异常的处理介绍完毕。

posted @ 2011-08-24 02:03 ♂风车车 阅读(...) 评论(...) 编辑 收藏