您的位置:首页 > 编程语言

.NET 4 并行(多核)编程系列之三 从Task的取消

2014-03-12 19:29 453 查看
原文:.NET 4 并行(多核)编程系列之三 从Task的取消
.NET 4 并行(多核)编程系列之三 从Task的取消

  前言:因为Task是.NET 4并行编程最为核心的一个类,也我们在是在并行编程常常打交道的类,所以,对Task对全面的了解很有必要。

  上篇文章主要讲述了如何创建一个task,本篇文章主要讲述如何取消一个task。

  本篇主的主要议题如下:

1.   1. 通过轮询的方式检测Task是否被取消

2.   2. 用委托delegate来检测Task是否被取消

3.    3. 用Wait Handle还检测Task是否被取消

4.   4. 取消多个Task

5.   5. 创建组合的取消Task的Token

6.   6. 判断一个Task是否已经被取消了

  系列文章链接:

  .NET 4 并行(多核)编程系列之一入门介绍

  .NET 4 并行(多核)编程系列之二 从Task开始

  .NET 4 并行(多核)编程系列之三 从Task的取消

  .NET 4 并行(多核)编程系列之四 Task的休眠

  .NET 并行(多核)编程系列之五 Task执行和异常处理

  .NET 并行(多核)编程系列之六 Task基础部分完结篇

  .NET 并行(多核)编程系列之七 共享数据问题和解决概述

本篇的理论不多,代码的例子很多。

在TPL中一个标准化的操作就是”取消Task”。之所以说它是个标准化的操作,其实是把这个操作和之前传统的多线程编程进行比较而言的。

在之前的多线程编程中,我们一般是自己写一些代码来取消线程的运行。但是在.NET 4的TPL中就内置了取消的方法,可能我们觉得TPL没有必要内置这些代码,因为太简单了。但是这个内置的方法不仅仅只是取消了运行的Task,而且还减小了在取消运行的Task时可能产生的一些风险,我们后续文章会详细讲述。

创建一个取消的Task一般要进行下面一些步骤:

a.     a.创建System.Threading.CancellationTokenSource的一个实例:

// create the cancellation token source
CancellationTokenSource tokenSource = new CancellationTokenSource();

b.     b.通过CancellationTokenSource.Token属性获得一个System.Threading.CancellationToken:

    

CancellationToken token = tokenSource.Token;

    c.创建一个新的Task或者Task<T>,并且在构造函数传入Action或者Action<object>的委托作为第一个参数,传入CancellationToken作为第二个参数:

Task task = new Task(new Action(printMessage), token);

d.     d.调用Task的Start()方法。

    上面的步骤和我们之前介绍的创建一个Task的代码几乎一样,只是在构造函数中多传入了一个参数。

    如果想要取消一个Task的运行,只要调用CancellationToken实例的Cancel()方法就可以了。

    有点要特别注意的,当我们调用了Cancel()方法之后,.NET Framework不会强制性的去关闭运行的Task。

    我们自己必须去检测之前在创建Task时候传入的那个CancellationToken。

    我们在创建Task是传入CancellationToken到构造函数,其实这个CancellationToken就是.NET Framework用来避免我们再次运行已经被取消的Task,可以说就是一个标志位。

  首先,进入第一个议题:

  1. 通过轮询的方式检测Task是否被取消

  在很多Task内部都包含了循环,用来处理数据。我们可以在循环中通过CancellationToken的IsCancellationRequest属性来检测task是否被取消了。如果这个属性为true,那么我们就得跳出循环,并且释放task所占用的资源(如数据库资源,文件资源等).

  我们也可以在task运行体中抛出System.Threading.OperationCanceledException来取消运行的task。

    代码如下:

代码

static void Main(string[] args)
{
// create the cancellation token source
CancellationTokenSource tokenSource1 = new CancellationTokenSource();

// create the cancellation token
CancellationToken token1 = tokenSource1.Token;

// create the first task, which we will let run fully
Task task1 = new Task(() =>
{
for (int i = 0; i < 10; i++)
{
token1.ThrowIfCancellationRequested();
Console.WriteLine("Task 1 - Int value {0}", i);
}
}, token1);

// create the second cancellation token source
CancellationTokenSource tokenSource2 = new CancellationTokenSource();

// create the cancellation token
CancellationToken token2 = tokenSource2.Token;

// create the second task, which we will cancel
Task task2 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
token2.ThrowIfCancellationRequested();
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, token2);

// start all of the tasks
task1.Start();
task2.Start();

// cancel the second token source
tokenSource2.Cancel();
// write out the cancellation detail of each task
Console.WriteLine("Task 1 cancelled? {0}", task1.IsCanceled);
Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);
// wait for input before exiting
Console.WriteLine("Main method complete. Press enter to finish.");
Console.ReadLine();
}

今天就写到这里,比较的简单,都是一些很基础的东西,只有这样,后面深入讲解的时候才更加的顺利。

谢谢各位!

   版权为小洋和博客园所有,转载请标明出处给作者。

   http://www.cnblogs.com/yanyangtian
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: