第八节: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 ...
随机推荐
- Python基础——3特性
特性 切片 L=[0,1,2,3,4,5,6,7,8,9,10] L[:3]=[0,1,2] L[-2:]=[9,10] L[1:3]=[1,2] L[::3]=[0,3,6,9] L[:5:2]=[ ...
- jQuery each、节点操作、动画演示、尺寸操作、扩展方法
一.each 1.方式一:$.each(数组或者自定义对象,function(i,j){console.log(i,j)}) $.each(li,function(i,j){ console.log( ...
- 如何在本地搭建DVWA环境
如何在本地搭建DVWA环境 1.工具下载: (1)phpStudy: http://phpstudy.php.cn/download.html (2)DVWA:http://www.dvwa.c ...
- .net core iis配置
微软官方教程: https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=aspnetcore2x 在vs中创建.net cor ...
- nginx上配置phpmyadmin
Nginx配置phpmyadmin流程如下: 一.准备软件和环境(这里我以ubuntu16.04为例) 1.安装php7.1 sudo LC_ALL=C.UTF- add-apt-repository ...
- Mac中安装git后,终端运行git出错,提示安装Xcode
mac用户不使用Xcode安装git之后,默认安装路径是: /usr/local/git 但是在终端运行 git 命令时候的路径是: /usr/bin/git 当我们输入 git 命令时出现如下错误, ...
- 基于Grunt构建一个的项目
没有搭建环境的,请参考<Grunt自动化构建环境搭建 >,搭建完成后 新建一个项目目录,这里建立一个“Demo”目录 运行CMD,并进入这个目录,运行 npm install grunt ...
- iview 无法缓存的问题
- Java的selenium代码随笔(4)
//高亮操作元素public void highlight(WebElement webElement) {JavascriptExecutor javascriptExecutor = (Javas ...
- mysql varchar integer
MySQL 中将 varchar 字段转换成数字进行排序 - MySQL - 大象笔记 https://www.sunzhongwei.com/order-by-varchar-field-which ...