第八节: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 ...
随机推荐
- Spring boot admin 节点状态一直为DOWN的排查
项目中需要监控各个微服务节点的健康状态,找到了spring boot admin这个全家桶监控工具,它其实是Vue.js美化过的Spring Boot Actuator,官方的解释是: codecen ...
- kunbernetes-快速入门
1.入门概述 本文以在容器云上部署一个nexus3应用为例,通过通过一步步的操作,帮助用户快速的对Kubernetes有一个快速和整体的认识.通过快速入门,可以提供如下知识内容: 在集群中部署一个容器 ...
- vue 组件中的钩子函数 不能直接写this
export default { data(){ return { num: 18 } }, beforeRouteEnter(to, from, next){ next(vm=>{ vm.nu ...
- koa 中间件
什么是 Koa 的中间件 通俗的讲:中间件就是匹配路由之前或者匹配路由完成做的一系列的操作,我们就可以 把它叫做中间件. 在express中间件(Middleware)是一个函数,它可以访问请求对象( ...
- isPrototypeOf、instanceof、hasOwnProperty函数介绍
isPrototypeOf 作用:检测一个对象是否是另一个对象的原型.或者说一个对象是否被包含在另一个对象的原型链中 var p = {x:1};//定义一个原型对象 var o = Object.c ...
- Java list 转字符串并加入分隔符的方法
import org.apache.commons.lang.StringUtils; List<String> list=new ArrayList<String>(); l ...
- python字符串replace失效问题
python字符串replace替换无效 背景 今天想把一个列表中符合条件的元素中 替换部分字符串, 发现怎么替换,改元素还是没有改变,本以为是内存引用的问题后来发现并不然. 经查阅解决 在Pytho ...
- python之shutil
''' shutil 用来处理 文件 文件夹 压缩包 的模块 ''' import shutil # 拷贝文件内容 shutil.copyfileobj(open('old.xml', 'r'), o ...
- Linux内存管理 (21)OOM
专题:Linux内存管理专题 关键词:OOM.oom_adj.oom_score.badness. Linux内核为了提高内存的使用效率采用过度分配内存(over-commit memory)的办法, ...
- Python#常用的模块和简单用法
目录 random 随机模块 os 文件夹模块: time 时间模块: matplotlab.pyplot 作图模块 mpl_toolkits.mplot3d 绘制3D图模块 Pygame Reque ...