Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务。对于将一个任务放进线程池     ThreadPool.QueueUserWorkItem(A);

这段代码用Task来实现的话,方式如下:     Task.Factory.StartNew(A);

这两端代码的使用和实现的功能都十分相似。但和TheadPool相比,Task有着更多的功能,更加方便我们使用。

假如我们要创建三个任务,并等待它们完成。这个功能用TheadPool实现如下:

using (ManualResetEvent mre1 = new ManualResetEvent(false))     using (ManualResetEvent mre2 = new ManualResetEvent(false))     using (ManualResetEvent mre3 = new ManualResetEvent(false))     {         ThreadPool.QueueUserWorkItem(delegate         {             A();             mre1.Set();         });         ThreadPool.QueueUserWorkItem(delegate         {             B();             mre2.Set();         });         ThreadPool.QueueUserWorkItem(delegate         {             C();             mre3.Set();         });         WaitHandle.WaitAll(new WaitHandle[] { mre1, mre2, mre3 });     }

用Task类实现起来就相对简单多了:

Task t1 = Task.Factory.StartNew(delegate { A(); });     Task t2 = Task.Factory.StartNew(delegate { B(); });     Task t3 = Task.Factory.StartNew(delegate { C(); });     t1.Wait();     t2.Wait();     t3.Wait();

或者我们还可以这么写:

Task t1 = Task.Factory.StartNew(delegate { A(); });     Task t2 = Task.Factory.StartNew(delegate { B(); });     Task t3 = Task.Factory.StartNew(delegate { C(); });     Task.WaitAll(t1, t2, t3);

下面我们来简单的介绍一下Task的基本用法:

创建Task

创建Task有两种方式

  1. 通过构造函数创建 Task t1 = new Task(A);
  2. 通过TaskFactory创建 Task t1 = Task.Factory.StartNew(A);

这两种方式其实是一样的,第一种方式里面也传入了默认的TaskFactory——Task.Factory。TaskFactory起着对Task进行创建和调度管理的作用,类似于以前CTP版中的TaskManager,关于这个对象,后续会单独写一篇文章介绍。

开始运行Task

在上述两种创建Task方式中,方式1创建的Task并没有立即执行,需要手动调用t1.Start()来执行(类似于线程,需要手动执行)。而方式2创建的Task是立即执行的(类似于线程池,是自动执行的),从这两种方式的函数名称也可以看出这一点。

等待Task完成

等待Task完成的也有两种:

  1. 调用Task的成员函数t.Wait()。
  2. 调用Task的静态函数Task.WaitAll()或Task.WaitAny()。

这两种方式和.net中常用的WaitHandle差不多,这里就不多介绍了。

取消Task

取消Task的方式较CTP的时候复杂和强大了不少,后续加一个单独的篇章单独介绍。

异常处理

当Task在执行过程中发生异常时,该异常会在Wait或WaitAll等函数中重新throw。可以通过Task的Exception属性来获取发生的异常。

var t1 = Task.Factory.StartNew(() => { throw new Exception("t1 error occor"); });     var t2 = Task.Factory.StartNew(() => { throw new Exception("t2 error occor"); });
    try     {         Task.WaitAll(t1, t2);     }     catch (Exception)     {         Console.WriteLine(t1.Exception.InnerException.Message);         Console.WriteLine(t2.Exception.InnerException.Message);     }

获取Task的返回值

在CTP版本中,是通过Fucture<>类来获取带返回值的Task的,现在已经将类改名为Task<>了,从而实现命名方式的统一。使用方式几乎一致,就是多了一个Result属性,可以在Task执行完成后获取返回值。示例如下:

);     t1.Wait();     Console.WriteLine(t1.Result);

其它

在Task中还有不少非常有用的任务调度和错误处理等的方法和属性,它们使得并发操作变得更为强大和简单,以后会陆续介绍这些知识。

.Net4.0并行库介绍——Task的更多相关文章

  1. .Net4.0并行库介绍——Cancellation Framework

    在.net 4.0中,引入了一个新的类CancellationToken,这个类基本上集成了我们各种常用的取消方式,在并发任务中非常有用. 同步模式下的取消: 一种比较常见的需要支持取消功能的的是一些 ...

  2. .Net4.0如何实现.NET4.5中的Task.Run及Task.Delay方法

    前言 .NET4.0下是没有Task.Run及Task.Delay方法的,而.NET4.5已经实现,对于还在使用.NET4.0的同学来说,如何在.NET4.0下实现这两个方法呢? 在.NET4.0下, ...

  3. C#当中的多线程_任务并行库(上)

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  4. .NET异步程序设计之任务并行库

    目录 1.简介 2.Parallel类 2.0 Parallel类简介 2.1 Parallel.For() 2.2 Parallel.ForEach() 2.3 Parallel.Invoke() ...

  5. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  6. .Net4.0 任务(Task)[转]

    .Net4.0 任务(Task) 任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks ...

  7. .Net4.0 任务(Task)

    任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks 命名空间下任务相关类一览: 类 ...

  8. C#多线程编程系列(五)- 使用任务并行库

    目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...

  9. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

随机推荐

  1. StringBuilder基本用法

    //StringBuilder用法 public class StringBuilderTest { public static void main(String[] args) { StringBu ...

  2. set -o vi AIX下shell

    set -o vi 再用esc+K键就可以使用上一条指令了 esc+kesc+j上下翻 ksh默认是emacs风格的.set -o emacs 在AIX下使用自己已经使用过的命令 在AIX下使用,默认 ...

  3. MyBatis3-与Spring MVC 4集成

    继前一篇的例子http://www.cnblogs.com/EasonJim/p/7052388.html,已经集成了Spring框架,现在将改造成Spring MVC的项目,并实现如下功能: 1.不 ...

  4. Python+Selenium 自动化实现实例-获取测试对象的Css属性

    #coding:utf-8 '''获取测试对象的css属性场景 当你的测试用例纠结细枝末节的时候,你就需要通过判断元素的css属性来验证你的操作是否达到了预期的效果.比如你可以通过判断页面上的标题字号 ...

  5. hdu 5468(dfs序+容斥原理)

    Puzzled Elena Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  6. Sublime Text 2.0.2,Build 2221注册码

    Help ->Enter License,输入如下序列号: ----- BEGIN LICENSE ----- Andrew Weber Single User License EA7E-855 ...

  7. html5多媒体Video/Audio

    video:    1.常见的视频格式 视频的组成部分:画面.音频.编码格式 视频编码:H.264.theora.VP8(google开源)      2.常见的音频格式     编码:AAC.MP3 ...

  8. Python使用opencv

    Python配置opencv 原理 Python调用opencv的原理是:opencv编译出共享库文件,python把这个共享库文件作为一个模块加载并使用. 通俗点就是,编译opencv的时候开启py ...

  9. [实战]MVC5+EF6+MySql企业网盘实战(14)——逻辑重构

    写在前面 上篇文章关于修改文件夹和文件名称导致的找不到物理文件的问题,这篇文章将对其进行逻辑的修改. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6 ...

  10. 【LOJ】 #2011. 「SCOI2015」情报传递

    题解 一写过一交A的一道数据结构水题 我们发现大于C可以转化为这条路径上有多少个在某天之前开始调查的情报员,离线全部读入,变成树上路径查询某个区间的数出现过多少次,构建一棵根缀的主席树,查询的时候用两 ...