第八节:Task的各类Task<TResult>返回值以及通用线程的异常处理方案。
一. 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. 线程开启类的返回值
{
Task<string> task1 = Task.Factory.StartNew(() =>
{
Console.WriteLine("我是子线程哦");
return "ok";
});
task1.Wait();
Console.WriteLine("我是主线程,我要读取子线程task1的返回值为:{0}", task1.Result);
}

2. 线程延续类的返回值
{
Task<int> task1 = Task.Run(() =>
{
Console.WriteLine("我是子线程1哦");
return ;
});
var task2 = task1.ContinueWith((t) =>
{
Console.WriteLine("我是子线程2哦");
//这里的t代表 task1
var num = t.Result + ;
return num.ToString();
});
task2.Wait();
Console.WriteLine("我是主线程,我要读取子线程task1的返回值为:{0}", task1.Result);
Console.WriteLine("我是主线程,我要读取子线程task2的返回值为:{0}", task2.Result);
}

3. 线程条件延续类
{
Task<int> task1 = Task.Run(() =>
{
Console.WriteLine("我是子线程1哦");
return ;
});
Task<int> task2 = Task.Run(() =>
{
Console.WriteLine("我是子线程2哦");
return ;
});
var task = Task.WhenAny(new Task<int>[] { task1, task2 });
task.Wait();
//下面的值可能是1,也可能是2
Console.WriteLine("我是主线程,我要读取子线程task的返回值为:{0}", task.Result.Result);
}

二. 通用线程异常处理方案
1. 背景:我们想达到一个目的,当同时开启多个线程的时候,其中一个线程报错,不影响其他线程的执行,并且能把错误记下来。
2. 解决方案:多重try-catch,整个外侧主线程一个try-catch,然后线程执行业务再用一个try-catch包裹起来。
常规方式捕获异常:
{
try
{
for (int i = ; i < ; i++)
{
string name = string.Format("name{0}", i);
var task = Task.Run(() =>
{
try
{
//模拟某个线程出错
if (name == "name2")
{
throw new Exception(string.Format("线程执行失败,i={0}", name));
}
else
{
Console.WriteLine(string.Format("线程执行执行成功,i={0}", name));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
运行结果:我们发现所有的线程均执行完毕,且name2执行失败,并捕获。

补充一下:通过 AggregateException 类来捕获异常。
{
try
{
for (int i = ; i < ; i++)
{
string name = string.Format("name{0}", i);
var task = Task.Run(() =>
{
throw new Exception(string.Format("线程执行失败,i={0}", name));
});
taskList.Add(task);
}
Task.WaitAll(taskList.ToArray());
}
catch (AggregateException aes)
{
foreach (var item in aes.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
}

第八节:Task的各类Task<TResult>返回值以及通用线程的异常处理方案。的更多相关文章
- Spring Boot Web 自定义返回值(通用)
在项目下新建common.entity包,包中包含两个文件Result数据类,ResultCode接口文件 Result.class @Data @NoArgsConstructor public c ...
- 【C# Task】 ValueTask/Task<TResult>
概要 1.如果异步方法的使用者使用 Task.WhenAll 或 Task.WhenAny,则在异步方法中使用 ValueTask<T> 作为返回类型可能会产生高昂的成本.这是因为您需要使 ...
- .NET - Task.Run vs Task.Factory.StartNew
翻译自 Stephen Toub 2011年10月24日的博文<Task.Run vs Task.Factory.StartNew>,Stephen Toub 是微软并行计算平台团队的首席 ...
- Java多线程-Callable的Future返回值的使用
一般使用线程池执行任务都是调用的execute方法,这个方法定义在Executor接口中: public interface Executor { void execute(Runnable comm ...
- ASP.NET Core中的Action的返回值类型
在Asp.net Core之前所有的Action返回值都是ActionResult,Json(),File()等方法返回的都是ActionResult的子类.并且Core把MVC跟WebApi合并之后 ...
- Java线程:新特征-有返回值的线程
http://lavasoft.blog.51cto.com/62575/222082/ Java线程:新特征-有返回值的线程 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 ...
- JAVAEE——SpringMVC第二天:高级参数绑定、@RequestMapping、方法返回值、异常处理、图片上传、Json交互、实现RESTful、拦截器
1. 课前回顾 https://www.cnblogs.com/xieyupeng/p/9093661.html 2. 课程计划 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 ...
- ResponseBodyAdvice如何处理返回值是字符串的问题
项目中使用ResponseBodyAdvice同一封装返回格式,对于一般的类型都没有问题,但是处理字符串时,遇到了类型转换的问题,debug一步一步跟踪,原来是对于字符串的ContentType是“t ...
- C#异步编程のTask模型返回值Task<TResult>应用
文中所有Task<TResult>的返回值都是直接用task.result获取,这样如果后台任务没有执行完毕的话,主线程会等待其执行完毕,这样的话就和同步一样了(看上去一样,但其实awai ...
随机推荐
- SQLServer之FOREIGN KEY约束
FOREIGN KEY约束添加规则 1.外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列. 2.如果在 FOREIGN KEY 约束的列中输入非 NU ...
- LeetCode算法题-Design LinkedList(Java实现)
这是悦乐书的第300次更新,第319篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第168题(顺位题号是707).设计链表的实现.您可以选择使用单链表或双链表.单链表中的 ...
- python 之 查找某目录中最新的文件
记录一下这个方法,感觉很有用!>.< import os def find_newest_file(path_file): lists = os.listdir(path_file) li ...
- 码农人生——从未学过Android如何开发Android App 案例讲解-第002期案例
标题有点晃眼,本次分享是002期博文的实践故事,不会有任何代码.也不会教别人android 如何开发,类似博文已经有大批大批,而且还会有陆陆续续的人写,我写的文章,主要是经验之谈,希望总结出的一些方法 ...
- Spring事件和监听器
Application下抽象子类ApplicationContextEvent的下面有4个已经实现好的事件 ContextClosedEvent(容器关闭时) ContextRefreshedEven ...
- 转://ORA-00603,ORA-27501,ORA-27300,ORA-27301,ORA-27302故障案例一则
背景介绍: 这是一套windows的rac系统.数据库后台日志报ORA-00474:SMON process terminated with error.接着报ORA-00603,ORA-27501, ...
- 19 python初学(os 模块,sys 模块,hashlib 模块)
os 模块: # _author: lily # _date: 2019/1/13 import os print(os.getcwd()) # 得到当前的工作目录 # print(os.chdir( ...
- yidiandian
hzwer libreoj (需要拿新版的打开)
- Linux内存管理 (3)内核内存的布局图
专题:Linux内存管理专题 关键词:内核内存布局图.lowmem线性映射区.kernel image.ZONE_NORMAL.ZONE_HIGHMEM.swapper_pg_dir.fixmap.v ...
- mybatis从mapper接口跳转到相应的xml文件的eclipse插件
mybatis从mapper接口跳转到相应的xml文件的eclipse插件 前提条件 开发软件 eclipse 使用框架 mybatis 为了方便阅读源码,项目使用mybatis的时候,方便从mapp ...