建议86:Parallel中的异常处理
建议85阐述了如何处理Task中的异常。由于Task的Start方法是异步启动的,所以我们需要额外的技术来完成异常处理。Parallel相对来说就要简单很多,因为Parallel的调用者线程会等到所有的任务全部完成后,再继续自己的工作。简单来说,它具有同步的特性,所以,用下面的这段代码就可以实现将并发异常包装到主线程中:
static void Main(string[] args) { try { var parallelExceptions = new ConcurrentQueue<Exception>(); Parallel.For(0, 1, (i) => { try { throw new InvalidOperationException("并行任务中出现的异常"); } catch (Exception e) { parallelExceptions.Enqueue(e); } if (parallelExceptions.Count > 0) throw new AggregateException(parallelExceptions); }); } catch (AggregateException err) { foreach (Exception item in err.InnerExceptions) { Console.WriteLine("异常类型:{0}{1}来自: {2}{3}异常内容:{4}", item.InnerException.GetType(), Environment.NewLine, item.InnerException.Source, Environment.NewLine, item.InnerException.Message); } } Console.WriteLine("主线程马上结束"); Console.ReadKey(); } |
这段代码的输出为:
异常类型:System.InvalidOperationException 来自:ConsoleApplication2 异常内容:并行任务中出现的异常 主线程马上结束 |
在Parallel的异常处理中,我们使用了一个线程安全的泛型集合ConcurrentQueue<T>来处理并发中有可能会遇到的集合线程安全性问题(参见建议22:确保集合的线程安全)。
相关链接:
连载1 连载2 连载3 连载4 连载5 连载6 连载7 连载8 连载9
连载10 连载11 连载12 连载13 连载14 连载15 连载71 连载72 连载73
连载74 连载75 连载76 连载77 连载78 连载79 连载80 连载81 连载82
连载83 连载84 连载85