烟台制作网站,wp网站开发,北京产品网站建设,域名查询注册商一. Task的各种返回值-TaskTResult PS#xff1a; 在前面章节#xff0c;我们介绍了Task类开启线程、线程等待、线程延续的方式#xff0c;但我们并没有关注这些方式的返回值#xff0c;其实他们都是有返回值的TaskTResult#xff0c;然后可以通过Task的…一. Task的各种返回值-TaskTResult PS 在前面章节我们介绍了Task类开启线程、线程等待、线程延续的方式但我们并没有关注这些方式的返回值其实他们都是有返回值的TaskTResult然后可以通过Task的实例调用Result属性来获取这个返回值。 下面我们分三类来介绍 ①线程开启类的返回值, 使用TaskTResult接受或者直接使用Task接受通过 实例.Result 来获取返回值。这里的线程开启类有多种eg: Task.Run()、 task.start()、 Task.Factory.StartNew() 等。 ②线程延续类的返回值. egContinueWith。 ③线程条件延续类的返回值. egWhenAll和WhenAny。 1. 线程开启类的返回值 1 {
2 Taskstring task1 Task.Factory.StartNew(()
3 {
4 Console.WriteLine(我是子线程哦);
5 return ok;
6 });
7 task1.Wait();
8 Console.WriteLine(我是主线程我要读取子线程task1的返回值为{0}, task1.Result);
9 } 2. 线程延续类的返回值 1 {2 Taskint task1 Task.Run(() 3 {4 Console.WriteLine(我是子线程1哦);5 return 2;6 });7 8 var task2 task1.ContinueWith((t) 9 {
10 Console.WriteLine(我是子线程2哦);
11
12 //这里的t代表 task1
13 var num t.Result 2;
14 return num.ToString();
15 });
16
17 task2.Wait();
18 Console.WriteLine(我是主线程我要读取子线程task1的返回值为{0}, task1.Result);
19 Console.WriteLine(我是主线程我要读取子线程task2的返回值为{0}, task2.Result);
20 } 3. 线程条件延续类 1 {2 Taskint task1 Task.Run(() 3 {4 Console.WriteLine(我是子线程1哦);5 return 1;6 });7 Taskint task2 Task.Run(() 8 {9 Console.WriteLine(我是子线程2哦);
10 return 2;
11 });
12
13 var task Task.WhenAny(new Taskint[2] { task1, task2 });
14 task.Wait();
15
16 //下面的值可能是1也可能是2
17 Console.WriteLine(我是主线程我要读取子线程task的返回值为{0}, task.Result.Result);
18 } 二. 通用线程异常处理方案
1. 背景我们想达到一个目的当同时开启多个线程的时候其中一个线程报错不影响其他线程的执行并且能把错误记下来。
2. 解决方案多重try-catch整个外侧主线程一个try-catch然后线程执行业务再用一个try-catch包裹起来。
常规方式捕获异常 1 {2 try3 {4 for (int i 0; i 5; i)5 {6 string name string.Format(name{0}, i);7 var task Task.Run(() 8 {9 try
10 {
11 //模拟某个线程出错
12 if (name name2)
13 {
14 throw new Exception(string.Format(线程执行失败i{0}, name));
15 }
16 else
17 {
18 Console.WriteLine(string.Format(线程执行执行成功i{0}, name));
19 }
20 }
21 catch (Exception ex)
22 {
23 Console.WriteLine(ex.Message);
24 }
25
26 });
27 taskList.Add(task);
28 }
29 Task.WaitAll(taskList.ToArray());
30 }
31 catch (Exception ex)
32 {
33 Console.WriteLine(ex.Message);
34
35 }
36 } 运行结果我们发现所有的线程均执行完毕且name2执行失败并捕获。 补充一下通过 AggregateException 类来捕获异常。 1 {2 try3 {4 for (int i 0; i 5; i)5 {6 string name string.Format(name{0}, i);7 var task Task.Run(() 8 {9 throw new Exception(string.Format(线程执行失败i{0}, name));
10 });
11 taskList.Add(task);
12 }
13 Task.WaitAll(taskList.ToArray());
14 }
15 catch (AggregateException aes)
16 {
17 foreach (var item in aes.InnerExceptions)
18 {
19 Console.WriteLine(item.Message);
20 }
21 }
22 }