您的位置:首页 > 编程语言 > C#

C#当中的多线程_任务并行库(下)

2015-12-22 15:34 471 查看
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         }


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: