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. 大型网站的 HTTPS 实践(二)——HTTPS 对性能的影响(转)

    原文链接:http://op.baidu.com/2015/04/https-s01a02/ 1 前言 HTTPS 在保护用户隐私,防止流量劫持方面发挥着非常关键的作用,但与此同时,HTTPS 也会降 ...

  2. 5.rabbitmq 主题

    1.生产者 #!/usr/bin/env python import pika import sys connection = pika.BlockingConnection(pika.Connect ...

  3. HDU 1217 Arbitrage(Bellman-Ford判断负环+Floyd)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目大意:问你是否可以通过转换货币从中获利 如下面这组样例: USDollar 0.5 Brit ...

  4. Hadoop案例(五)过滤日志及自定义日志输出路径(自定义OutputFormat)

    过滤日志及自定义日志输出路径(自定义OutputFormat) 1.需求分析 过滤输入的log日志中是否包含xyg (1)包含xyg的网站输出到e:/xyg.log (2)不包含xyg的网站输出到e: ...

  5. 面试题13:在O(1)时间删除链表节点

    注意分情况讨论: 1. 要删除的不是尾节点 2. 链表只有一个节点 3. 链表中有多个节点,删除尾节点 void DeleteNode(ListNode** pListHead, ListNode* ...

  6. Tarojs+redux支付宝小程序开发攻略

    技术选型 对于习惯react语法的开发者来讲,RN是实现native的必备工具. 我们甚至可以屏蔽官方稳定而强大的配置层,直接上手开发. 而后,同为表层React语法的Rax.Taro这样的开源多端开 ...

  7. bzoj 1110 贪心 + 进制转换

    思路:感觉脑洞好大啊... 因为每两个砝码其中一个都是另一个的倍数,我们可以知道砝码的种数很少,我们将所有容器的 容量都转换成用这些砝码的重量的进制表示,然后将所有砝码排序,然后贪心地取,取到不能再取 ...

  8. JavaScript三种数据类型之间的互转

    一:number<===>string  数字类型和字符串类型之间的互相转换 number===>string 数字转字符串有三种方式: 1.在数字后面 +“ ”; 2.利用字符串的 ...

  9. Docker入门到实战

    1.系统要求 Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10. CentOS 7满足最低内核的要求,但由于内核版本比较低,部分功能(如 overlay2 存 ...

  10. 【codeforces.com/gym/100240 J】

    http://codeforces.com/gym/100240 J [分析] 这题我搞了好久才搞出样例的11.76....[期望没学好 然后好不容易弄成分数形式.然后我‘+’没打..[于是爆0... ...