C# Task 的用法(转自:http://www.wxzzz.com/683.html#)

其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观。代码更简洁了,使用Task来进行操作。可以跟线程一样可以轻松的对执行的方法进行控制。

顺便提一下,配合CancellationTokenSource类更为可以轻松的对Task操作的代码进行中途终止运行,会在后面的章节中讲述。

如果我们使用线程池来实现某几个方法运行,然后等待运行完成的大概会编写如下代码:

  1. using (ManualResetEvent m1 = new ManualResetEvent(false))
  2. using (ManualResetEvent m2 = new ManualResetEvent(false))
  3. {
  4. ThreadPool.QueueUserWorkItem(delegate
  5. {
  6. MyMethodA();
  7. m1.Set();
  8. });
  9. ThreadPool.QueueUserWorkItem(delegate
  10. {
  11. MyMethodB();
  12. m2.Set();
  13. });
  14. WaitHandle.WaitAll(new WaitHandle[] { m1, m2, });
  15. }

如果用Task类的话,相对就比较简单了,至少代码看起来很舒服。也就意味着维护也比较方便

  1. Task t1 = Task.Factory.StartNew(delegate { MyMethodA(); });
  2. Task t2 = Task.Factory.StartNew(delegate { MyMethodB(); });
  3. t1.Wait();
  4. t2.Wait();

上面的方法是一个一个的执行完毕,获取不是我们想要的,我们一般是想要他们一起同时执行,提高程序处理事情的效率。

  1. Task t1 = Task.Factory.StartNew(delegate { MyMethodA(); });
  2. Task t2 = Task.Factory.StartNew(delegate { MyMethodB(); });
  3. Task.WaitAll(t1, t2);

下面我们来简单介绍下Task的用法

创建 Task

创建Task有两种方式,一种是使用构造函数创建,另一种是使用 Task.Factory.StartNew 进行创建。如下代码所示

1.使用构造函数创建Task

  1. Task t1 = new Task(MyMethod);

2.使用Task.Factory.StartNew 进行创建Task

  1. Task t1 = Task.Factory.StartNew(MyMethod);

其实这两种方式都是一样的,Task.Factory 是对Task进行管理,调度管理这一类的。好学的伙伴们,可以深入研究。这不是本文的范畴,也许会在后面的文章细说。

运行 Task

运行Task的两种方式,在上面我们已经提到过了,一种等待运行完毕,另一种则等待所有运行完毕。不过这里还有一种就是异步运行,跟使用多线程一样,调用Task对象中的Start()方法即可。看看下面这个控制台示例。纯粹是Wait和AllWait的话,仅仅是等待。而不是执行。所以我们还需要调用Start()方法

  1. static void Main(string[] args)
  2. {
  3. Task t1 = new Task(MyMethod);
  4. t1.Start();
  5. Console.WriteLine("主线程代码运行结束");
  6. Console.ReadLine();
  7. }
  8. static void MyMethod()
  9. {
  10. for (int i = 0; i < 5; i++)
  11. {
  12. Console.WriteLine(DateTime.Now.ToString());
  13. Thread.Sleep(1000);
  14. }
  15. }

运行效果如图

因为我们没有调用Wait 所以是异步执行的~

取消Task

我们一开始就描述了 CancellationTokenSource 这个对象对Task的取消运行。一般是用不到这个方法的,一般会正常的退出所运行的代码,如使用 bool IsExit 之类的来进行一个控制。而不是中途强制中断代码。

可以参考我的这篇文章:http://www.wxzzz.com/643.html

至于 CancellationTokenSource 控制Task,下一篇文章会进行详细的一个介绍。

Task的异常处理

因为Task中是异步执行,你也可以理解为跟多线程一样,具体错误捕获需要自己去捕获。很有意思的是Task的异常还会重新抛到Wait和AllWait中,我们可以进行方便的捕获这些异常。如下代码

  1. static void Main(string[] args)
  2. {
  3. Task t1 = new Task(MyMethod);
  4. t1.Start();
  5. t1.Wait();
  6. Console.WriteLine("主线程代码运行结束");
  7. Console.ReadLine();
  8. }
  9. static void MyMethod()
  10. {
  11. throw new Exception("Task异常测试");
  12. }

运行效果如图

获取 Task 的返回值

先看看代码

  1. Task<string> t1 = Task.Factory.StartNew(() => "测试");
  2. t1.Wait();
  3. Console.WriteLine(t1.Result);
  4. Console.ReadLine();

返回值可以是任意的类型,因为是个泛型嘛~ 还是依然的非常简洁的代码。

至此,就是 C# Task 的相关用法了,欢迎回复讨论。

C# Task 的用法的更多相关文章

  1. C# Task的用法

    C# Task 的用法 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 顺便提一下, ...

  2. 多线程 thread和Task的用法以及注意事项

    并行 多核线程:Task 首先引用System.Threading; 1:用静态方法:Task.Factory.StartNew()来创建了一个最简单的Task: Task.Factory.Start ...

  3. Task 的用法

    Task的功能喝Thread类似,写法也很简单: 两种方式: 第一 Task t1=new Task(()=>{}); t1.Start();//启动Task t1.Wait();//若调用Wa ...

  4. verilog中task的用法

    任务就是一段封装在“task-endtask”之间的程序.任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的.调用某个任务时可能需要 ...

  5. 浅谈Task的用法

    Task是用来实现多线程的类,在以前当版本中已经有了Thread及ThreadPool,为什么还要提出Task类呢,这是因为直接操作Thread及ThreadPool,向线程中传递参数,获取线程的返回 ...

  6. C#线程学习笔记七:Task详细用法

    一.Task类简介: Task类是在.NET Framework 4.0中提供的新功能,主要用于异步操作的控制.它比Thread和ThreadPool提供了更为强大的功能,并且更方便使用. Task和 ...

  7. Task的用法

    创建任务 无返回值的方式 方式1: var t1 = new Task(() => TaskMethod("Task 1")); t1.Start(); Task.WaitA ...

  8. C# Task 用法

    C# Task 的用法 其实Task跟线程池ThreadPool的功能类似,不过写起来更为简单,直观.代码更简洁了,使用Task来进行操作.可以跟线程一样可以轻松的对执行的方法进行控制. 顺便提一下, ...

  9. C# Task用法

    1.Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如: ◆ ThreadPool不支持线程的取消.完成.失败通知等交互性 ...

随机推荐

  1. 数据集(benchmark)、常用数据集的解析(cifar-10、)

    What is the class of this image ? 主要是以下常见的数据集,用以衡量算法的分类准确率: mnist.cifar-10.cifar-100stl-10 svhn.ILSV ...

  2. Cordova 代码热更新 - 简书

    原文:Cordova 代码热更新 - 简书 Cordova 代码热更新 [图片上传失败...(image-a19be7-1521624289049)] 基于 Cordova 框架能将网页应用 (js, ...

  3. ubuntu 16.0.4 中docker 部署 sqlserver 2017(四)

    1. 从 Docker Hub 中拉出 SQL Server 2017 Linux 容器映像 sudo docker pull mcr.microsoft.com/mssql/server:2017- ...

  4. Android中的事件处理研究

    处理用户界面事件Handling UI Events 在Android上,不止一个途径来侦听用户和应用程序之间交互的事件.对于用户界面里的事件,侦听方法就是从与用户交互的特定视图对象截获这些事件.视图 ...

  5. c语言学习笔记(13)——链表

    链表 算法: 1.通俗定义: 解题的方法和步骤 2.狭义定义: 对存储数据的操作 3.广义定义: 广义的算法也叫泛型 无论数据是如何存储的,对数据的操作都是一样的 我们至少可以通过两种结构来存储数据 ...

  6. TBB、OpenCV混合编程

    TBB提供了Parallel_for.Parallel_do.Parallel_reduce等通用并行算法,可以应用在不同的并行算法场合,Parallel_for适合用在多个数据或请求之间彼此没有依赖 ...

  7. March 29th, 2015, Thread Name is odd by increasing 1

    public class Fabric extends Thread{ public static void main(String args[]){ Thread t = new Thread(ne ...

  8. beego中各类数据库连接方式

    beego 框架是优秀得go REST API开发框架.下面针对beego中各类数据库连接操作做一个总结. 1. orm连接方式 beego中的orm操作支持三种数据库:mysql,sqlite3,p ...

  9. 32位与64位、单精度(single-precision)与双精度(double-precision)

    What's the difference between a single precision and double precision floating point operation? 0. 6 ...

  10. 第一个spring boot工程

    参考. 1. 碰到的问题: -出现bind:address already in use是因为当前项目正在运行,停掉当前项目即可.cmd中命令 netstat -nao 查看所有占用的端口及PID号, ...