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. Eclipse3.6 添加JUnit源代码

    Eclipse中无法查看JUnit源代码,也无法设置源代码的jar. 解决方法: 1.  下载org.junit.source_4.8.1.v4_8_1_v20100427-1100.jar,放到ec ...

  2. android JB2连拍降速原理介绍

    1.HAL层 (1)alps\mediatek\platform\mt6589\hardware\camera\core\camshot\MultiShot\MultiShot.cpp sleep实现 ...

  3. Android创建与读取Excel

    主流的操作Excel的有两种方法,一种是通过poi包,另一种是通过jxl包.这里我主要讲解通过jxl包来读写Excel. 首先需要导入一个jxl.jar包. 下载地址:http://www.andyk ...

  4. struts+hibernate 请求数据库增删改查(小项目实例)

      StudentAction.java package com.action; import java.util.ArrayList; import java.util.List; import j ...

  5. 14 - XML、JSON、PLIST对比和APP生命周期

    XML中间的 数据表达/传输数据的语言 优点:特别强大 强大到很多平台都有基于XML的独立语言,如MXML.HTML 缺点:传输小型数据时,特别啰嗦 size / speed = time JSON ...

  6. 高级UIKit-02(文件操作)

    [day3_1_Sandbox]:沙箱的介绍 snadbox沙箱沙盒 沙箱根目录下的几个文件夹: 1.应用名称.app存放应用程序的素材 2.Documents:存放应用运行时需要用到的数据(关键性数 ...

  7. 基于RAF的一个小动画框

    RAF也即是requestAnimationFrame,之前的动画都是基于setTimeout写的,所以为了性能方面的考虑,开始使用requestAnimationFrame写动画. function ...

  8. X窗口系统名词解释

    前端时间Gentoo的桌面环境出了点问题,发现自己对Linux的桌面环境了解的很少,于是恶补了一下知识,以下名词解释基本上都是来自维基百科的条目和<Linux程序设计(第三版)>.一般而言 ...

  9. APEC计划指引我们前进:云计算服务将上升

    APEC纲领指引我们前进:云计算服务业必将兴起 这是APEC领导人的合影: 这次APEC会议通过了<北京纲领>和<亚太伙伴关系声明>,进一步明白了亚太地区经济合作的发展方向.目 ...

  10. iphone分辨率终极指南(含有iphone6/6+)

    如文本不清楚.请 "对->图片另存为" 下载大图后, ------------------------- 原文及翻译文本 Points点 At the beginning, ...