一. Task的各种返回值-Task<TResult>

PS: 在前面章节,我们介绍了Task类开启线程、线程等待、线程延续的方式,但我们并没有关注这些方式的返回值,其实他们都是有返回值的Task<TResult>,然后可以通过Task的实例调用Result属性来获取这个返回值。

  下面我们分三类来介绍:

  ①:线程开启类的返回值, 使用Task<TResult>接受,或者直接使用Task接受,通过 实例.Result 来获取返回值。这里的线程开启类有多种,eg: Task.Run()、 task.start()、 Task.Factory.StartNew() 等。

  ②:线程延续类的返回值. eg:ContinueWith。

  ③:线程条件延续类的返回值. eg:WhenAll和WhenAny。

 1. 线程开启类的返回值

1             {
2                 Task<string> 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                 Task<int> 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                 Task<int> task1 = Task.Run(() =>3                 {4                     Console.WriteLine("我是子线程1哦");5                     return 1;6                 });7                 Task<int> task2 = Task.Run(() =>8                 {9                     Console.WriteLine("我是子线程2哦");
10                     return 2;
11                 });
12
13                 var task = Task.WhenAny(new Task<int>[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             }

第八节:Task的各类TaskTResult返回值以及通用线程的异常处理方案相关推荐

  1. 第八节:Task的各类TaskTResult返回值以及通用线程的异常处理方案。

    一. Task的各种返回值-Task<TResult> PS: 在前面章节,我们介绍了Task类开启线程.线程等待.线程延续的方式,但我们并没有关注这些方式的返回值,其实他们都是有返回值的 ...

  2. c# 使用多个TASK事务,等待返回值

    在一个有返回值的方法中,我们启用三个事务分别处理数据,每个事务假设耗时为两秒,代码如下: private List<string> Test(){//事务列表List<Task< ...

  3. form表单ajax提交 ac,請求Ajax 帶返回值的通用方法, 自動獲取頁面控件值(form表單post方法提交 ),自動給控件賦值...

    //自動獲取頁面控件值 function GetWebControls(element) { var reVal = ""; $(element).find('input,sele ...

  4. python多线程处理数据并获得子线程返回值

    python多线程处理数据并获得子线程返回值 前言 python3中的多线程 用方法包装函数 用类包装函数 获取子线程返回值 从类中返回值 其他方法 前言 python中采用多线程方式处理大数据量的数 ...

  5. linux获取命令的返回值,Shell $?:获取函数返回值或者上一个命令的退出状态

    $?是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态,就是上一个命令执行后的返回结果.退出状态是一个数字,一般情况下,大部分命令执行成功会返回0,失败返回1,这和C ...

  6. Go 学习笔记(61)— Go 高阶函数、函数作为一等公民(函数作为输入参数、返回值、变量)的写法

    函数在 Go 语言中属于"一等公民(First-Class Citizen)"拥有"一等公民"待遇的语法元素可以如下使用 可以存储在变量中: 可以作为参数传递给 ...

  7. Thrift解读(五)——server端RPC接收与返回值的回送

    Thrift框架主要分为四层:Service,Protocol,Transport,Server.前述介绍的TNonBlockingServer就是一种Server,除此之外,还有很多别的Server ...

  8. java开启线程的方法_Java有几种方法开启线程?怎么实现带有返回值的线程?

    Java有几种方法开启线程?怎么实现带有返回值的线程? 发布时间:2020-05-22 11:20:08 来源:亿速云 阅读:238 作者:Leah Java有几种方法开启线程?怎么实现带有返回值的线 ...

  9. async js 返回值_图文讲解浏览器执行JS过程中的微任务和宏任务

    背景 我们知道浏览器有一个特定的事件执行机制,专业名词叫做Event Loop.如下图所示,浏览器会优先执行同步代码,遇到异步的代码时,会被挂起并在需要执行的时候加入到 Task(有多种 Task) ...

最新文章

  1. c 语言socket粘包,C# Socket粘包处理讲解示例
  2. 使用inetaddress测试目标可达性_白盒测试工具―Winams介绍
  3. PHP学习笔记-Cookie
  4. 2020 我的C++学习之路 C++PrimerPlus第八章课后习题
  5. ceshildkd 124
  6. 请求头Content-Type:application/json,java后端如何接收数据
  7. 为什么python的命名不能以数字开头,Python模块名称以数字开头
  8. 在RDA上使用mbed编译运行KWS
  9. python列表数据类型一致_python自学——数据类型之列表
  10. swift python javascript_最小的Swift App
  11. Linux 的内存分页管理
  12. google四件套之Dagger2。从入门到爱不释手,之:Dagger2进阶知识及在Android中使用
  13. 怎么用计算机解锁手机密码华为,华为手机忘记解锁密码如何解锁?两招轻松搞定...
  14. 戴尔笔记本电脑光驱装固态,并设置为系统盘教程
  15. onedrive教育版登录不上
  16. 生僻字用计算机怎么弹歌曲,抖音生僻字计算器乐谱 计算器弹歌曲音乐乐谱大全...
  17. 微信小程序wx.onLocationChange的使用,并计算移动距离
  18. MySql8JDBC操作
  19. 腾格里沙漠部分污染地被填埋 记者采访被限自由
  20. Java图片Base64互转

热门文章

  1. 题目一:给出一个n,代表有从1到n的数字[1,2,3,··· n],问可以构成多少种二叉搜索树?...
  2. Datagridview绘制
  3. SVG_text.动态创建换行显示(横)
  4. 一个伟大计划终于完成了(粉丝联盟网正式上线了)
  5. DotNET内存管理与垃圾回收[转]
  6. 拓扑排序两种实现方式
  7. java aac rtp封装_分享一段H264视频和AAC音频的RTP封包代码
  8. python怎么读取github_六行代码获取Github排名前10的Python项目
  9. 隐藏该监视器无法显示模式_【春星开讲 | 9137】达芬奇4K调色监看的好伙伴——明基PD2720U专业显示器...
  10. java api帮助文档_JAVA的Swagger界面丑、功能弱怎么破?