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. Window文本在Linux中出现的^M问题

    问题:在Windows中写了一个shell脚本在Linux中死活不能运行,怎么也查不出错误,原来是格式问题. 原因:Windows/DOS系统的换行符是/r/n,Unix/Linux系统的换行符是/n ...

  2. BootStarp的form表单的基本写法

    代码如下: <!DOCTYPE html> <html> <head> <title>BootStrap的基础入门</title> < ...

  3. python_xlsxwriter模块

    1.workbook类 add_worksheet 用于添加一个新的工作表,sheetname为工作表名称,默认是sheet1,例如: worksheet = workbook.add_workshe ...

  4. DB2:FETCH FIRST 1 ROWS ONLY

    DB2:FETCH FIRST ROWS ONLY,在Oracle中使用where rownum=1代替 DB2: SELECT INSTORAGENO FROM ( SELECT max(AUDIT ...

  5. Reverse Linked List I&&II——数据结构课上的一道题(经典必做题)

    Reverse Linked List I Question Solution Reverse a singly linked list. Reverse Linked List I 设置三个指针即可 ...

  6. bug优先级定义

    优先级定义如下: <版本前期阶段>(功能刚提测): [P0—紧急]:完全不能满足产品要求,基本功能明显未实现或完全不可用,阻塞测试流程与进度(核心功能流程) 1.功能未实现 .功能缺失 2 ...

  7. Redis 启动与授权

    启动 Redis $redis-server 检查Redis是否在工作? $redis-cli 这将打开一个Redis提示,如下图所示: redis 127.0.0.1:6379> 上面的提示1 ...

  8. HTML5 canvas绘制arcTo、translate和rotate的画法探索

      arcTo(x1,y1,x2,y2,radius) ; 还要加上moveTo的点(x0,y0) ; 第一步:找到切点 过点 (x1,y1), (x0,y0)引射线与点(x1,y1),(x2,y2) ...

  9. CentOS 7安装Mysql并设置开机自启动的方法

    CentOS 7不带Mysql数据库了,默认的数据库是MariaDB(Mysql的一个分支). 可以按照以下步骤手动安装Mysql数据库. 1. 下载rpm安装文件 ? 1 wget http://r ...

  10. 使用cp命令时候递归的创建目标目录

    在使用cp命令拷贝文件的时候,有时候会遇到这样的场景: 源文件:/a/b/c/e.txt 目标地址:/mnt/a/b/c/e.txt 而/mnt/a/b/c这个目录结构还没有创建.拷贝的时候还要求目录 ...