在.net 4.0中,引入了一个新的类CancellationToken,这个类基本上集成了我们各种常用的取消方式,在并发任务中非常有用。

同步模式下的取消:

一种比较常见的需要支持取消功能的的是一些比较耗时的分段操作:如视频转换,网络下载等,这种方式下的取消机制如下:

  1. 建立一个标记位,表示该操作是否已经取消
  2. UI线程在获取到取消事件后,置标记位为true
  3. 耗时的操作线程里,没进行一小段操作之后查询该标记位,如果为true则主动退出。

使用方式如下:

;         ; i < ; i++)         {             ; j < ; j++)             {                 total++;             }             if (token.IsCancellationRequested)             { // observe cancellation                 throw new OperationCanceledException(token); // acknowledge cancellation             }         }         return total;     }

异步模式下的取消

另外一种常见的方式是在一些异步操作中,往往不能主动释放,只能等待异步操作回调的时候才能操作结果。此时一般取消方法如下:

  1. 任务线程注册异步操作完成的回调函数,开始异步操作。
  2. UI线程接受取消指令,置取消标记位,并主动执行回调函数
  3. 回调函数中通过取消标记位判断该任务是已经完成还是被取消的,并执行相关析构操作。

使用方式如下:

void BlockingOperation(CancellationToken token)     {         ManualResetEvent mre = new ManualResetEvent(false);         //register a callback that will set the MRE         CancellationTokenRegistration registration =            token.Register(() => mre.Set());         using (registration)         {             mre.WaitOne();             if (token.IsCancellationRequested) //did cancellation wake us?                 throw new OperationCanceledException(token);         } //dispose the registration, which performs the deregisteration.     }

这里我们通过CancellationToken注册了一个回调方法以通知任务等待线程,也可以以我们经常使用的WaitHandle的那样的方式使用。

void Wait(WaitHandle wh, CancellationToken token)     {         WaitHandle.WaitAny(new[] { wh, token.WaitHandle });         if (token.IsCancellationRequested) //did cancellation wake us?             throw new OperationCanceledException(token);     }

高级应用

由于例子比较简单,这里就只列举一下代码,不多介绍了。

一个CancellationToken对应多个任务

void Example4()     {         CancellationTokenSource cts = new CancellationTokenSource();         Func1(cts.Token);         Func2(cts.Token);         Func3(cts.Token);         //...         cts.Cancel(); // all listeners see the same cancellation request.     }

一个任务对应多个CancellationToken

void LinkingExample(CancellationToken ct1, CancellationToken ct2)     {         CancellationTokenSource linkedCTS =         CancellationTokenSource.CreateLinkedTokenSource(ct1, ct2);         try         {             SlowFunc(linkedCTS.Token);         }         catch (OperationCanceledException oce)         {             if (ct1.IsCancellationRequested)             {                 // ...             }             else if (ct2.IsCancellationRequested)             {                 // ...             }         }         linkedCTS.Dispose(); // clean up the linking. required.     }

最后我们再来一个并发查询时取消的例子:

, , };         CancellationTokenSource cts = new CancellationTokenSource();         var query = data.AsParallel()                      .WithCancellation(cts.Token) // token given to library code                      .Select((x) => SlowFunc(x, cts.Token)); // token passed to user code     }
    private int SlowFunc(int x, CancellationToken token)     {        int result        while(...)        {           if (token.IsCancellationRequested)              throw new OperationCanceledException(token);           ...        }        return result;     }

小结

.net 4.0中的Cancellation Framework还是非常实用的,通过它可以更有效的简化及规范的使用各种取消的操作方式,由于我也只会皮毛,在这里也只是介绍了它的基本用法,在后续的学习和应用中将继续进一步介绍。

.Net4.0并行库介绍——Cancellation Framework的更多相关文章

  1. .Net4.0并行库介绍——Task

    Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务.对于将一个任务放进线程池     ThreadPool.QueueUserWorkItem(A); 这段代码用Task来实现 ...

  2. C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是TAP(Task-based Asynchronous Pattern, 基于任务的异步模式)

    学习书籍: <C#本质论> 1--C#5.0之后推荐使用TPL(Task Parallel Libray 任务并行库) 和PLINQ(Parallel LINQ, 并行Linq). 其次是 ...

  3. C#多线程编程系列(五)- 使用任务并行库

    目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...

  4. .Net4.0 任务(Task)[转]

    .Net4.0 任务(Task) 任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks ...

  5. Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介

    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...

  6. C#多线程开发-任务并行库04

    你好,我是阿辉. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑, ...

  7. C#当中的多线程_任务并行库(上)

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  8. Android开发中用到的框架、库介绍

    Android开发中用到的框架介绍,主要记录一些比较生僻的不常用的框架,不断更新中...... 网路资源:http://www.kuqin.com/shuoit/20140907/341967.htm ...

  9. .Net4.0 任务(Task)

    任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks 命名空间下任务相关类一览: 类 ...

随机推荐

  1. linux -j 4

    把源码编译成可执行的二进制文件, 4为服务器内核数

  2. leetcode 之Search in Rotated Sorted Array(四)

    描述 Follow up for ”Search in Rotated Sorted Array”: What if duplicates are allowed?    Would this aff ...

  3. CSU 1424 Qz’s Maximum All One Square

    原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1424 逐渐找到做这种题的感觉了. 二分法.g[i][j]存储坐标(i, j)的值,s[i ...

  4. IOS - Safari中click点击事件无效

    做web移动端页面时,安卓端一点问题也没,发现在ios真机上点击事件无效,发现Safari下只有默认可点击的元素才click点击事件,像span div等元素是不具有点击事件的. 解决问题四种方式: ...

  5. C# HTML 生成 PDF

    原文出处:http://www.cnblogs.com/shanyou/archive/2012/09/07/2676026.html

  6. ES6-Set 和 Map 数据结构

    ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. const s = new Set(); [2, 3 ...

  7. python笔记五:IO与文件

    1.python IO:  Python提供了两个内置函数从标准输入读入一行文本,默认的标准输入是键盘:  1)raw_input([prompt]) 函数从标准输入读取一个行,并返回一个字符串  2 ...

  8. java项目日志系统的总结

    目录 日志系统归类以及关系 日志的三个组件 slf4j的使用 项目中构建日志系统 使用例子 日志系统归类以及关系 常用的日志框架: slf4j.logback .log4j.log4j2.JUL(ja ...

  9. luogu P4115 Qtree4

    题目链接 luogu P4115 Qtree4 题解 动态点分治,和上一题一样.同样三个堆.就是带权,用边权替换深度就好 为什么要单独写这个题解呢,因为我卡常卡了一天....据说树剖比rmq快? 在第 ...

  10. 51nod部分容斥题解

    51nod1434 区间LCM 跟容斥没有关系.首先可以确定的一个结论是:对于任意正整数,有1*2*...*n | (k+1)*(k+2)*...*(k+n).因为这就是$C_{n+k}^{k}$. ...