一. 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>返回值以及通用线程的异常处理方案。的更多相关文章

  1. Spring Boot Web 自定义返回值(通用)

    在项目下新建common.entity包,包中包含两个文件Result数据类,ResultCode接口文件 Result.class @Data @NoArgsConstructor public c ...

  2. 【C# Task】 ValueTask/Task<TResult>

    概要 1.如果异步方法的使用者使用 Task.WhenAll 或 Task.WhenAny,则在异步方法中使用 ValueTask<T> 作为返回类型可能会产生高昂的成本.这是因为您需要使 ...

  3. .NET - Task.Run vs Task.Factory.StartNew

    翻译自 Stephen Toub 2011年10月24日的博文<Task.Run vs Task.Factory.StartNew>,Stephen Toub 是微软并行计算平台团队的首席 ...

  4. Java多线程-Callable的Future返回值的使用

    一般使用线程池执行任务都是调用的execute方法,这个方法定义在Executor接口中: public interface Executor { void execute(Runnable comm ...

  5. ASP.NET Core中的Action的返回值类型

    在Asp.net Core之前所有的Action返回值都是ActionResult,Json(),File()等方法返回的都是ActionResult的子类.并且Core把MVC跟WebApi合并之后 ...

  6. Java线程:新特征-有返回值的线程

    http://lavasoft.blog.51cto.com/62575/222082/ Java线程:新特征-有返回值的线程 2009-11-04 17:33:56 标签:返回值 职场 线程 休闲 ...

  7. JAVAEE——SpringMVC第二天:高级参数绑定、@RequestMapping、方法返回值、异常处理、图片上传、Json交互、实现RESTful、拦截器

    1. 课前回顾 https://www.cnblogs.com/xieyupeng/p/9093661.html 2. 课程计划 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 ...

  8. ResponseBodyAdvice如何处理返回值是字符串的问题

    项目中使用ResponseBodyAdvice同一封装返回格式,对于一般的类型都没有问题,但是处理字符串时,遇到了类型转换的问题,debug一步一步跟踪,原来是对于字符串的ContentType是“t ...

  9. C#异步编程のTask模型返回值Task<TResult>应用

    文中所有Task<TResult>的返回值都是直接用task.result获取,这样如果后台任务没有执行完毕的话,主线程会等待其执行完毕,这样的话就和同步一样了(看上去一样,但其实awai ...

随机推荐

  1. HTML之间互相传参

    如图所示,在index.html详情展示中给detailsPanel穿参数,在detailsPanel中获取到参数写ajax到后台获取json数据,那么如何在detailsPanel.html中获取传 ...

  2. elementUI el-select 中disabled设置

    <el-select v-model="userForm.roleName" placeholder="请选择用户角色" :disabled=" ...

  3. final等关键字和代码块

    一.final关键字 其作用 1.final除构造方法外均可修饰 2.修饰类:被final修饰的类是无法被继承的. 3.修饰方法,可被继承,但是无法被重写 4.修饰变量使其为常量 5.修饰引用型变量, ...

  4. 日志级别的选择:Debug、Info、Warn、Error

    日志信息分类 1.等级由低到高:debug<info<warn<Error: 2.区别: debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东: ...

  5. Linux内核入门到放弃-页缓存和块缓存-《深入Linux内核架构》笔记

    内核为块设备提供了两种通用的缓存方案. 页缓存(page cache) 块缓存(buffer cache) 页缓存的结构 在页缓存中搜索一页所花费的时间必须最小化,以确保缓存失效的代价尽可能低廉,因为 ...

  6. 使用BigQuery分析GitHub上的C#代码

    一年多以前,Google 在GitHub中提供了BigQuery用于查询的GitHub上的开源代码(open source code on GitHub available for querying) ...

  7. Mybatis逆向工程 —— ResultMaps collection already contains value for ***

    报错提示: Result Maps collection already contains value for ***. 遭遇场景: maven+ssm 项目中,采用了mybatis的逆向工程生成 p ...

  8. python获取list列表随机数据

    第一种方法(推荐)适用于随机取一个值, 返回一个值import randomlist1 = ['佛山', '南宁', '北海', '杭州', '南昌', '厦门', '温州']a = random.c ...

  9. java高级-动态注入替换类Instrumentation

    介绍 利用java.lang.instrument(容器类) 做动态 Instrumentation(执行容器) 是 Java SE 5 的新特性. 使用 Instrumentation,开发者可以构 ...

  10. Express使用art-template模板引擎

    第一步:安装 npm install --save art-template npm install --save express-art-template 第二步:指定.html使用的解析引擎(官方 ...