使用TPL取回Task中的运行结果的三种方式
概念:TPL( Task Parallel Library) 任务并行库
使用Task类执行多线程操作要比直接使用自己手工创建Thread效率高很多。
默认情况下,TPL使用线程池中的线程执行Task,但是工作结束之后,调用者线程怎么取回执行线程的工作结果呢?
这里有三种方法:
1.使用经典的线程同步手段:
可以使用线程同步对象。比如ManualResetEvent

在任务方法中设置ManualResetEvent状态为Signaled

调用者示例代码:

示例代码:
/// <summary>
/// 用于保存处理结果的共享资源
/// </summary>
private static long result = ;
/// <summary>
/// 用于通知启动任务的线程处理工作已完成
/// </summary>
static ManualResetEvent mre = new ManualResetEvent(false);
static void Main(string[] args)
{
Action<object> taskMethod = (end) =>
{
long sum = ;
for (int i = ; i < (int) end; i++)
sum += i;
//保存处理结果(使用Interlocked实现原子操作,无需加锁)
Interlocked.Exchange(ref result, sum);
//通知调用者,工作已经完成,可以取回结果了
mre.Set();
};
//启动异步任务
Task tsk = new Task(taskMethod,);
tsk.Start();
//等待并行处理的完成已取回结果
mre.WaitOne();
Console.WriteLine("程序运行结果为{0}",Program.result);
Console.ReadKey();
}
这种方法混杂了TPL与传统多线程开发方式,不推荐使用
2.使用Task<T>,Result属性

示例代码:
static void Main(string[] args)
{
Func<object, long> del = (end) =>
{
long sum = ;
for (int i = ; i < (int) end; i++)
sum += i;
return sum;
};
Task<long> tsk = new Task<long>(del,);
tsk.Start();
Console.WriteLine("程序运行结果为{0}",tsk.Result);
Console.ReadKey();
}
这种编程方式代码简洁,开发中可用,但是调用者线程必须阻塞等待任务结束。不适合在服务端应用中使用
3.基于回调模式的结果取回
TPL中有一个ContinueWith()方法,可用于创建前赴后继的工作任务

这里调用者线程不是阻塞等待的。适合在服务端应用程序中使用。
示例代码
static void Main(string[] args)
{
Func<object, long> ProcessData = (end) =>
{
long sum = ;
for (int i = ; i < (int)end; i++)
{
sum += i;
throw new DivideByZeroException();
}
return sum;
};
//用于取回处理结果的函数
Action<Task<long>> GetResult = (finishedTask) =>
{
//依据任务状态,决定后继处理工作
if (finishedTask.IsFaulted)
Console.WriteLine("任务在执行时发生异常:{0}", finishedTask.Exception);
else
Console.Write("程序运行结果为{0}", finishedTask.Result);
}; //创建并行处理数据的任务对象
Task<long> tskProcess = new Task<long>(ProcessData, ); //当数据处理结束时,自动启动下一个工作任务,取回上一任务的处理结果
Task tskGetResult = tskProcess.ContinueWith(GetResult); //开始并行处理数据……
tskProcess.Start(); Console.ReadKey();
}
使用TPL取回Task中的运行结果的三种方式的更多相关文章
- 在Tomcat中部署web项目的三种方式
搬瓦工搭建SS教程 SSR免费节点:http://www.xiaokeli.me 在这里介绍在Tomcat中部署web项目的三种方式: 1.部署解包的webapp目录 2.打包的war文件 3.Man ...
- Tomcat中部署web应用的三种方式
Tomcat中部署web应用的三种方式(静态部署) 第一种,针对war或解压后的war,最为常用的是直接操作webapp目录,将完整的war包或者web应用直接放到webapp目录下.使用 ...
- spring中创建bean对象的三种方式以及作用范围
时间:2020/02/02 一.在spring的xml配置文件中创建bean对象的三种方式: 1.使用默认构造函数创建.在spring的配置文件中使用bean标签,配以id和class属性之后,且没有 ...
- Linux中设置服务自启动的三种方式
有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s 在/etc/rc.d/rc*.d目录中建立/e ...
- [转]Linux中设置服务自启动的三种方式
from:http://www.cnblogs.com/nerxious/archive/2013/01/18/2866548.html 有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统 ...
- Linux中设置服务自启动的三种方式,ln -s 建立启动软连接
有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务(http://www.0830120.com) 主要用三种方式进行这一操作: ln -s 在/etc/rc.d/rc*.d目录中建立 ...
- (转)Linux中设置服务自启动的三种方式
有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s 在/etc/rc.d/rc*.d目录中建立/e ...
- 【转发】Linux中设置服务自启动的三种方式
有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s 在/etc/rc.d/rc*.d目录中建立/e ...
- Java中 实现多线程成的三种方式(继承,实现,匿名内部类)
---------------------------------------------------------------------------------------------------- ...
随机推荐
- Unrecognized SSL message, plaintext connection--SSLSocket 代理服务器连接
虽然java代码 URL.openconnect(proxy);已经实现了https客户端通过代理连接服务器 但个人在使用socket https代理http://www.cnblogs.com/h ...
- Python之基本的日期与时间转换 datetime、 dateutil模块
简单举例datetime模块 from datetime import timedelta,datetime a = timedelta(days=2, hours=6) b = timedelta( ...
- 浅析Mysql事务传播行为
传播行为 1.PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置. 2.PROPAGATION_SUPPORTS:支持当 ...
- webacp4.0
'use strict';const path = require('path'); var APP_PATH = path.resolve(__dirname, 'src');const webpa ...
- linux起源及centos安装
第1章 Linux介绍 1.1 什么是操作系统 是一个人与计算机硬件的中介 Linux:内核+shell+扩展软件 操作系统,英文名称Operating System,简称OS,是计算机系统中必不可 ...
- go语言从例子开始之Example18_1.结构体中定义方法
Go 支持在结构体类型中定义方法 . Example: package main import "fmt" type product struct{ name string num ...
- springboot解决跨域
@Configuration public class WebMvcConfiguration implements WebMvcConfigurer { @Bean public CorsFilte ...
- double中首字母大写与小写的区别
Double 是类 double是基础数据类型.Double类型是double的包装类.Double 和double之间的相互转化称为自动拆箱和自动装箱.如果从对象角度理解,那么Double就是对象, ...
- Delphi 访问https /SSL、OpenSSL
访问 Web 网站,最简单用法直接使用 TIdHTTP 控件: 例如:AA := IdHTTP1.Get('www.baidu.com.'); 访问 https 的网站,需要 SSL 库. 在 Win ...
- 每天一个linux命令:touch(9)
touch touch命令有两个功能:一是用于把已存在文件的时间标签更新为系统当前的时间(默认方式),它们的数据将原封不动地保留下来:二是用来创建新的空文件 格式 touch [选项] [文件] 参数 ...