TPL异步并行编程之简单使用

在上篇随笔里面说明了Task的使用,仅仅是简单使用,有时候把一个任务交给Task去执行,但是呢还是要管理下,比如说:我要叫这个任务停止了,不做了,任务取消了,或者超时了

在传统的While里面我们可以这样做,1 通过标识 2 通过一个方法抛异常,3 其他办法

举个例子:while(true){

  if(isNotCancel){

    //每次都判断下,取消没有,当然isNotCancel需要加上lock的

  }

}

难道在Task里面有什么新奇吗?其实也没啥新奇的,那Task怎么取消呢?来点干货吧

一 轮训检测

直接调用task.cancel方法,但是下Task函数体内部必须做轮训检测是否被取消,且看代码

 static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task=new Task(() =>
{
while (true)
{
if (token.IsCancellationRequested)
{
break;
}
else
{ }
}
},token); Console.WriteLine("运行"); task.Start(); Thread.Sleep(*); tokenSource.Cancel(); Console.ReadKey();
}

二  取消过程拦截检测

在调用task.cancel方法是会在真正改变token.IsCancellationRequested值之前,调用token中所注册的函数,也就是说token.cancel(),调用后会调用token.register所注册的方法,然后再更改token.IsCancellationRequested只为true,那么反过来在注册的方法中我们就可以检测是否调用了cancel方法了也就自然检测到了已经取消了

且看代码说话:

 static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task=new Task(() =>
{
while (true)
{
if (token.IsCancellationRequested)
{
break;
}
else
{ }
}
},token); Console.WriteLine("运行"); token.Register(() =>
{
Console.WriteLine("取消了,在取消之前必定调用了我");
}); task.Start(); Thread.Sleep(*); tokenSource.Cancel(); Console.ReadKey();
}

三 使用信号量来检测是否取消

现在我们启用2个Task,TaskA,TaskB,TaskB需要TaskA取消后才能执行,那么我们也可以在TaskB中执行代码时检测TaskA已被取消了,且看代码

 static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; Task task=new Task(() =>
{
while (true)
{
// 一直在运行,下面那个家伙得等着我被取消或者把事情做完
if (token.IsCancellationRequested)
{
//我已被取消该时候退出了
break;
}
}
},token); Task.Run(() =>
{
//我一开始就被上面那个task家伙挂起了,我需要他取消我才能干活~~
token.WaitHandle.WaitOne();
while (true)
{
// 开始干活
}
}); task.Start(); Thread.Sleep(*); tokenSource.Cancel(); Console.ReadKey();
}

四 多个协作的Task一个取消则其他Task也被取消,这样也可以取消一组Task

就好比我们几个人一起干一件事情,但是这件事情需要每个分工的相互协作才能继续,比如玉女双休剑,需要2人同时练功才行,其中一个人说我不行了 那都不行了,且看代码

4.1 共用一个Token

 static void Main(string[] args)
{
CancellationTokenSource tokenSource = new CancellationTokenSource(); // create the cancellation token
CancellationToken token = tokenSource.Token; // create the tasks
Task task1 = new Task(() =>
{
for (int i = ; i < int.MaxValue; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Task 1 - Int value {0}", i);
}
}, token); Task task2 = new Task(() =>
{
for (int i = ; i < int.MaxValue; i++)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, token);
// wait for input before we start the tasks
Console.WriteLine("Press enter to start tasks");
Console.WriteLine("Press enter again to cancel tasks");
Console.ReadLine(); // start the tasks
task1.Start();
task2.Start(); // read a line from the console.
Console.ReadLine(); // cancel the task
Console.WriteLine("Cancelling tasks");
tokenSource.Cancel();
// wait for input before exiting
Console.WriteLine("Main method complete. Press enter to finish.");
Console.ReadLine();
}

4.2 Token组

 static void Main(string[] args)
{
// create the cancellation token sources
CancellationTokenSource tokenSource1 = new CancellationTokenSource();
CancellationTokenSource tokenSource2 = new CancellationTokenSource();
CancellationTokenSource tokenSource3 = new CancellationTokenSource(); // create a composite token source using multiple tokens
CancellationTokenSource compositeSource =
CancellationTokenSource.CreateLinkedTokenSource(
tokenSource1.Token, tokenSource2.Token, tokenSource3.Token); // create a cancellable task using the composite token
Task task = new Task(() =>
{
// wait until the token has been cancelled
compositeSource.Token.WaitHandle.WaitOne();
// throw a cancellation exception
throw new OperationCanceledException(compositeSource.Token);
}, compositeSource.Token); // start the task
task.Start(); // cancel one of the original tokens
Thread.Sleep(*);
tokenSource2.Cancel(); // wait for input before exiting
Console.WriteLine("Main method complete. Press enter to finish.");
Console.ReadLine();
}

五 抛出异常

ThrowIfCancellationRequested,在四中已经看到如果调用cancel方法会处罚ThrowIfCancellationRequested函数的执行,那么相应的Task检测到异常如果不做任何处理的情况下也就退出了,且看代码

 代码

 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->        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 = ; i < ; 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 = ; 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();
}

最后

其实取消Task的执行还有其他办法,也可以自己实现不一定就要TPL通过的api来实现

TPL异步并行编程之取消任务的更多相关文章

  1. TPL异步并行编程之简单使用

    并行编程一直是一个老生常谈的话题 在这里记录一下TPL编程,这在net4.0 微软就已经提供了多核时代下的并行库,其中最核心的最常用的也就是Task 一 Task是什么 Task可以简单的理解为一个线 ...

  2. TPL异步并行编程之回调

    Task是基于ThreadPool线程池基础上的高度异步多线程编程,如果有一天我希望一个需要长时间运行的Task,在被某些异常终止后还能回调一些代码就可以知道Task终止的原因了吧 是的,且看代码 p ...

  3. TPL异步并行编程之任务超时

    此处参考自阿涛的博文:http://www.cnblogs.com/HelloMyWorld/p/5526914.html 一 自己定义 基本的思路: net中异步操作由于是交给线程来实现,因此不可能 ...

  4. Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别

    Task C# 多线程和异步模型 TPL模型   Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...

  5. C# 异步编程3 TPL Task 异步程序开发

    .Net在Framework4.0中增加了任务并行库,对开发人员来说利用多核多线程CPU环境变得更加简单,TPL正符合我们本系列的技术需求.因TPL涉及内容较多,且本系列文章为异步程序开发,所以本文并 ...

  6. .NET Framework各版本比较

    (1)本文比较了.NET Framework多个版本之间的区别,方便各位选择和切换.NET Framework. 版本号 发布日期 Visual Studio的版本 Windows上的默认情况 CLR ...

  7. WinForm调用钉钉获取考勤结果

    关注点: 1.钉钉AccessToken的获取和防止过期 2.使用TPL并行编程调用钉钉接口 需求详解 公司前台有个大屏,领导想显示全部员工的考勤结果统计情况和车间的实时监控视频,还有车间的看板.简单 ...

  8. System.Threading.Tasks

    前言: 我们之前介绍了两种构建多线程软件的编程技术(使用异步委托或通过System.Threading的成员).这两个可以在任何版本的.NET平台工作. 关于System.Threading 的介绍 ...

  9. 使用JAVA CompletableFuture实现流水线化的并行处理,深度实践总结

    大家好,又见面啦. 在项目开发中,后端服务对外提供API接口一般都会关注响应时长.但是某些情况下,由于业务规划逻辑的原因,我们的接口可能会是一个聚合信息处理类的处理逻辑,比如我们从多个不同的地方获取数 ...

随机推荐

  1. 基于visual Studio2013解决算法导论之023队列实现(基于数组)

     题目 基于数组的队列 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> #i ...

  2. 基于visual Studio2013解决C语言竞赛题之0415特殊对数

       题目 解决代码及点评 这道题也是锻炼for循环,在for循环中遍历所有可能的数,然后再判断该数是不是有这样的性质 /********************************* ...

  3. MySQL中关于日期、时间的数据类型和函数

    一.日期相关的数据类型 1.datetime 占用8字节,既显示了日期,又显示了时间.其表示的日期范围为“1000-01-01 00:00:00”到“9999-12-31 23:59:59” 2.da ...

  4. 安装apk程序进android

    package com.example.installmyapk; import java.io.File; import android.net.Uri; import android.os.Bun ...

  5. C++多态原理

    C++的多态性是通过动态绑定实现的 非虚函数是在编译时绑定的; 通过对象进行的函数(虚函数,非虚函数)也是编译时绑定的; C++编译器在编译的时候,要确定每个对象调用的函数(要求此函数是非虚函数)的地 ...

  6. DP之花店橱窗布置

    题目:https://www.smartoj.com/p/1286 分析:花瓶是有序的,花也是有序的,这就保证了有序性,从而满足子解的全局最优,和无后效性.假设dp[i][j]表示前i 朵花,放在前j ...

  7. 闲扯 Javascript 00

    引言 Javascript  的作用在此就不阐述了,相信你已经知道它的用途!那我说点什么呢? 不如就和大家先扯一把,后面的工作 随后后展开吧! 首先声明:我个人对Javascript 认识,我只知道它 ...

  8. Linux 命令整理

    一.文件目录命令 1.建立目录:mkdir 目录名 2.删除空目录:rmdir 目录名 3.无条件删除子目录: rm -rf 目录名 4.改变当前目录:cd 目录名 (进入用户home目录:cd ~; ...

  9. Connection reset by peer问题分析

    extremetable导出excel,弹出一个下载窗口,这时不点下载而点取消,则报下面的异常: ClientAbortException Caused by: java.net.SocketExce ...

  10. php:兄弟连之面向对象版图形计算器2

    上篇说到通过result.class.php来分流,因为三个类都继承了shape这个类,让我们来看一下,面向对象中的继承. shape.class.shape文件 <?php abstract ...