标签:
4.8 处理任务中的异常
下面这个例子讨论了任务当中抛出异常,以及任务异常的获取
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //声明一个任务 6 Task<int> task; 7 //第一种方式,普通的try...catch捕获异常 8 try 9 { 10 task = Task.Run(() => TaskMethod("Task 1", 2)); 11 int result = task.Result; 12 Console.WriteLine("Result: {0}", result); 13 } 14 catch (Exception ex) 15 { 16 //这里捕获的异常是一个被封装的异常,叫做AggregateException 17 Console.WriteLine("Exception caught: {0}", ex); 18 Console.WriteLine("----------------------------------------------"); 19 //本例中AggregateException之中只有一个异常,因为只有一个任务抛出了异常 20 Console.WriteLine("InnerException is {0}",ex.InnerException.ToString()); 21 } 22 Console.WriteLine("----------------------------------------------"); 23 Console.WriteLine(); 24 25 //第二种方式是采用GetAwaiter().GetResult()方法来访问任务结果,这种方式可以提取没有封装的异常 26 try 27 { 28 task = Task.Run(() => TaskMethod("Task 2", 2)); 29 int result = task.GetAwaiter().GetResult(); 30 Console.WriteLine("Result: {0}", result); 31 } 32 catch (Exception ex) 33 { 34 Console.WriteLine("Exception caught: {0}", ex); 35 } 36 Console.WriteLine("----------------------------------------------"); 37 Console.WriteLine(); 38 39 40 //第三个demo展示了两个任务抛出异常的情形。 41 var t1 = new Task<int>(() => TaskMethod("Task 3", 3)); 42 var t2 = new Task<int>(() => TaskMethod("Task 4", 2)); 43 var complexTask = Task.WhenAll(t1, t2); 44 var exceptionHandler = complexTask.ContinueWith(t => 45 Console.WriteLine("Exception caught: {0}", t.Exception), 46 TaskContinuationOptions.OnlyOnFaulted 47 ); 48 t1.Start(); 49 t2.Start(); 50 51 Thread.Sleep(TimeSpan.FromSeconds(5)); 52 } 53 54 static int TaskMethod(string name, int seconds) 55 { 56 Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", 57 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); 58 Thread.Sleep(TimeSpan.FromSeconds(seconds)); 59 //抛出一个异常 60 throw new Exception("Boom!"); 61 return 42 * seconds; 62 } 63 }
结果如下
第一个demo
第二个demo
第三个demo
4.9 并行运行任务
这个小节主要讲述了Task.WhenAll()和Task.WhenAny()这两个方法,一个是等待所有任务全执行后的操作,一个是等待任何一个任务执行完的操作。
例子: 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //创建两个任务firstTask和secondTask 6 var firstTask = new Task<int>(() => TaskMethod("First Task", 3)); 7 var secondTask = new Task<int>(() => TaskMethod("Second Task", 2)); 8 //借助Task.WhenAll()方法创建第三个任务,该任务会在前两个任务完成后完成 9 var whenAllTask = Task.WhenAll(firstTask, secondTask); 10 //whenAllTask任务结束以后会产生一个结果数组, 11 //对应的第一个元素是第一个任务结果,第二个元素对应的是第二个任务结果... 12 whenAllTask.ContinueWith(t => 13 Console.WriteLine("The first answer is {0}, the second is {1}", t.Result[0], t.Result[1]), 14 TaskContinuationOptions.OnlyOnRanToCompletion 15 ); 16 17 firstTask.Start(); 18 secondTask.Start(); 19 20 Thread.Sleep(TimeSpan.FromSeconds(4)); 21 22 //这个demo,展示了启动一系列任务运行的过程 23 var tasks = new List<Task<int>>(); 24 for (int i = 1; i < 4; i++) 25 { 26 int counter = i; 27 var task = new Task<int>(() => TaskMethod(string.Format("Task {0}", counter), counter)); 28 tasks.Add(task); 29 task.Start(); 30 } 31 32 while (tasks.Count > 0) 33 { 34 //使用Task.WhenAny()方法等待任务当中的任何一个任务完成 35 var completedTask = Task.WhenAny(tasks).Result; 36 //每当一个任务完成,就把他从任务列表移除,直到任务列表为空 37 tasks.Remove(completedTask); 38 Console.WriteLine("A task has been completed with result {0}.", completedTask.Result); 39 } 40 41 Thread.Sleep(TimeSpan.FromSeconds(1)); 42 } 43 44 static int TaskMethod(string name, int seconds) 45 { 46 Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}", 47 name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread); 48 Thread.Sleep(TimeSpan.FromSeconds(seconds)); 49 return 42 * seconds 50 }
标签:
原文地址:http://www.cnblogs.com/dcz2015/p/5066836.html