简介

Task是在.NET Framework 4中添加进来的,这是新的namespace:System.Threading.Tasks;它强调的是adding parallelism and concurrency to applications

现在都是多核的CPU,在系统内,Task Parallel Library能更有效地利用CPU核心。TPL 会动态地按比例调节并发程度,以便最有效地使用所有可用的处理器。TPL 还处理工作分区、ThreadPool 上的线程调度、取消支持、状态管理以及其他低级别的细节操作。对比ThreadPool上的Thread并没有很好地支持Cancel的操作。

在语法上,和lambda表达式更好地结合。

创建Task

显式创建Task

先看一个简单的示例:

using System;
using System.Threading;
using System.Threading.Tasks;public class TaskExample1
{public static void Main(){Thread.CurrentThread.Name = "Main";// 使用lambda方式,之间提供一个用户delegate,创建一个TaskTask taskA = new Task( () => Console.WriteLine("From taskA."));// StarttaskA.Start();// Output a message from the calling thread.Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);//等待task结束taskA.Wait();}
}//       From thread 'Main'.
//       From taskA.

任务对象Task提供可在任务的整个生存期内从调用线程访问的方法和属性。例如,可以随时访问任务的 Status 属性,以确定它是已开始运行、已完成运行、已取消还是引发了异常。状态由 TaskStatus 枚举表示。

简化创建并开始的Task操作版本–直接使用一个操作: System.Threading.Tasks.Task.Run()

using System;
using System.Threading;
using System.Threading.Tasks;public class TaskExample2
{public static void Main(){Thread.CurrentThread.Name = "Main";// Define and run the task.Task taskA = Task.Run( () => Console.WriteLine("From taskA."));// Output a message from the calling thread.Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);taskA.Wait();}
}
//       From thread 'Main'.
//       From taskA.

TaskFactory创建Task

TPL提供了工厂类TaskFactory,也可用直接创建Task。 一个操作System.Threading.Tasks.TaskFactory.StartNew, 即可完成创建并开始一个Task.

Use this method when creation and scheduling do not have to be separated and you require additional task creaion options or the use of a specific scheduler, or when you need to pass additional state into the task through its AsyncState property, as shown in the following example.

using System;
using System.Threading;
using System.Threading.Tasks;public class TaskExample3
{public static void Main(){Thread.CurrentThread.Name = "Main";// 创建task并启动Task taskA = Task.Factory.StartNew(() => Console.WriteLine("From taskA."));// Console.WriteLine("From thread '{0}'.", Thread.CurrentThread.Name);// wait tasktaskA.Wait();                  }
}//       Hello from thread 'Main'.
//       Hello from taskA.

传入参数

来自MS的示例:

using System;
using System.Threading;
using System.Threading.Tasks;public class Example
{public static void Main(){Task[] taskArray = new Task[10];for (int i = 0; i < taskArray.Length; i++) {taskArray[i] = Task.Factory.StartNew( (int param) => {Console.WriteLine("Task #{0}.", param);},i );}Task.WaitAll(taskArray);     }
}

Task返回值

如果一个Task执行方法是有返回值的,可用得到其值。在创建一个task时,其返回的值为Task,表示一个返回类型为T的Task;在taks完成执行后,可用通过Task的Result属性获取结果。

public class Task<TResult> : System.Threading.Tasks.Task

来自MS的示例:

using System;
using System.Linq;
using System.Threading.Tasks;class Program
{static void Main(){// lambda表达式创建一个task并执行,并返回值。Task<int> task1 = Task<int>.Factory.StartNew(() => 1);int i = task1.Result;// 返回对象Task<Test> task2 = Task<Test>.Factory.StartNew(() =>{string s = ".NET";double d = 4.0;return new Test { Name = s, Number = d };});Test test = task2.Result;// Return an array produced by a PLINQ queryTask<string[]> task3 = Task<string[]>.Factory.StartNew(() =>{string path = @"C:\Users\Public\Pictures\Sample Pictures\";string[] files = System.IO.Directory.GetFiles(path);var result = (from file in files.AsParallel()let info = new System.IO.FileInfo(file)where info.Extension == ".jpg"select file).ToArray();return result;});foreach (var name in task3.Result)Console.WriteLine(name);}class Test{public string Name { get; set; }public double Number { get; set; }}
}

Continue操作

如果一个Task开始执行时间依赖于其它的Task的完成,可以使用Continue系列方法。

来自MS的示例:

using System;
using System.Threading.Tasks;public class Example
{public static void Main(){                         var getData = Task.Factory.StartNew(() => { Random rnd = new Random(); int[] values = new int[100];for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)values[ctr] = rnd.Next();return values;} );  var processData = getData.ContinueWith((x) => {int n = x.Result.Length;long sum = 0;double mean;for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)sum += x.Result[ctr];mean = sum / (double) n;return Tuple.Create(n, sum, mean);} ); var displayData = processData.ContinueWith((x) => {return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",x.Result.Item1, x.Result.Item2, x.Result.Item3);} );                         Console.WriteLine(displayData.Result);}
}// 输出:
//    N=100, Total = 110,081,653,682, Mean = 1,100,816,536.82

而且,可以使用更简化的写法.

using System;
using System.Threading.Tasks;public class Example
{public static void Main(){                         var displayData = Task.Factory.StartNew(() => { Random rnd = new Random(); int[] values = new int[100];for (int ctr = 0; ctr <= values.GetUpperBound(0); ctr++)values[ctr] = rnd.Next();return values;} ).  ContinueWith((x) => {int n = x.Result.Length;long sum = 0;double mean;for (int ctr = 0; ctr <= x.Result.GetUpperBound(0); ctr++)sum += x.Result[ctr];mean = sum / (double) n;return Tuple.Create(n, sum, mean);} ). ContinueWith((x) => {return String.Format("N={0:N0}, Total = {1:N0}, Mean = {2:N2}",x.Result.Item1, x.Result.Item2, x.Result.Item3);} );                         Console.WriteLine(displayData.Result);}
}

Cancel操作

在TPL中,为Task能cancel执行,提供了CancellationTokenSource和CancellationToken;
需要完成的工作是:在Task的action执行方法内,周期性地检查CancellationToken的IsCancellationRequested属性。
示例:

    private var tokenSource = new CancellationTokenSource();public void Start(){var token = tokenSource.Token;for (int i = 0; i<5; i++>) {Task t = Task.Factory.StartNew( () => DoSomeWork(i, token), token);Console.WriteLine("Task {0} executing", t.Id);}}public void Stop(){var token = tokenSource.Token;tokenSource.Cancel();}void DoSomeWork(int taskNum, CancellationToken ct){// 先检查,调度进入时,是否cancel了。if (ct.IsCancellationRequested == true) {Console.WriteLine("Task {0} was cancelled before it got started.",taskNum);ct.ThrowIfCancellationRequested(); // 抛出异常-- 或者 return} // 正式开始任务。 int maxIterations = 100;// NOTE!!! A "TaskCanceledException was unhandled for (int i = 0; i <= maxIterations; i++) {// var sw = new SpinWait();for (int j = 0; j <= 100; j++)sw.SpinOnce();if (ct.IsCancellationRequested) {Console.WriteLine("Task {0} cancelled", taskNum);ct.ThrowIfCancellationRequested(); //抛出异常-- 或者 return} } }

C#中的thread和task之Task相关推荐

  1. C#中的thread和task之 Thread ThreadPool

    简介 在.NET Framework/C#中,要提高系统的运行性能,可用使用Thread和新的Task. Thread在.NET Framework 1.1中引入,是对Posix的thread的封装. ...

  2. C#多线程之Thread,ThreadPool,Task,Parallel

    总目录 文章目录 总目录 前言 一.多线程以及与之相关概念 1.基本概念 1)进程 2)线程 3)多线程 2.同步.异步 1)同步方法 2)异步方法 二.Thread 1.线程的使用 1)创建并开启线 ...

  3. c# Thread、ThreadPool、Task有什么区别,什么时候用,以及Task的使用

    c# Thread.ThreadPool.Task有什么区别,什么时候用,以及Task的使用 这三者都是为了处理耗时任务,且都是异步的. Thread Thread就是Thread,需要自己调度,适合 ...

  4. 理解spark中的job、stage、task

    什么是Spark? Spark是处理大数据常用的计算引擎.Spark是一个用来实现快速而通用的集群计算的平台.扩展了广泛使用的MapReduce计算模型,而且高效地支持更多的计算模式,包括交互式查询和 ...

  5. 关于Android 中的Activity,Application和Task

    什么是Android  Application? 简单来说,一个apk文件就是一个Application. 任何一个Android Application基本上是由一些Activities组成,当用户 ...

  6. Android中使用Thread线程出现的问题

    很多初入Android或Java开发的新手对Thread.Looper.Handler和Message仍然比较迷惑,衍生的有HandlerThread.java.util.concurrent.Tas ...

  7. python的多线程threading_Python中多线程thread与threading的实现方法,pythonthreading

    Python中多线程thread与threading的实现方法,pythonthreading 学过Python的人应该都知道,Python是支持多线程的,并且是native的线程.本文主要是通过th ...

  8. Python中多线程thread与threading的实现方法

    Python中多线程thread与threading的实现方法 这篇文章主要介绍了Python中多线程thread与threading的实现方法,很重要的应用,需要的朋友可以参考下 学过Python的 ...

  9. Java中的Thread.sleep()– Java线程睡眠

    Java中的Thread.sleep (Thread.sleep in Java) Thread.sleep() method can be used to pause the execution o ...

最新文章

  1. 模态框到阻止冒泡时间
  2. 清华大学计算机系71班张晨,“神仙打架”要来了!网友:又到了凡人围观的时刻...
  3. 抖音小程序开发:CEO们涌进直播间带货
  4. UltraEdit常用配置搭建Java/C开发环境
  5. isset、empty、var==null、is_null、var===null详细理解
  6. 大部分人不知道的 5 个强大HTML5 API
  7. CodeFirst Update-Database 出现对象'DF__**__**__**' 依赖于 列'**'。
  8. Java 读取Oracle数据库中的Date日期型怎么去掉秒后面的0
  9. python 策略回测_python策略怎么进行全市场回测-金字塔知识 -程序化交易(CXH99.COM)...
  10. “冲击波”病毒的症状和解决方案
  11. 大数据学习入门规划?
  12. 风云2号卫星云图_中国为什么要发这么多卫星?答案没有出乎意料
  13. 一些比较舒服的rgb配色 (含rgb值,可参考)
  14. 第一个游戏外挂,附上详细制作过程
  15. Storyboard故事板
  16. 【连载】线性代数笔记——第二章矩阵
  17. 软件已删除,但在控制面板里还有,就是删不掉.怎么办?
  18. Arturia Buchla Easel V for Mac - Buchla音乐画架插件
  19. Windows 2003 工作手册
  20. lncRNASNP:SNP位点对lncNA结构和lncRNA-miRNA影响的数据库

热门文章

  1. linux - python
  2. 拥抱.NET Core系列:Logging (1)
  3. 深入理解计算机系统(2.3)---整数的表示方式精解无符号与补码编码(重要)...
  4. html alert 的三种方式
  5. FreeBSD下安装postfixl邮件系统
  6. Ajax.net实现的动态输入项
  7. python云计算面试题_云计算工程师面试问题及答案解析
  8. DWR的学习文档(Hello World,类型转换,Spring,Annotation)
  9. Pytorch(八) --Pytorch实现多分类问题
  10. [蓝桥杯][2015年第六届真题]表格计算(递归+记忆化)