在.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. java.lang.IllegalArgumentException: Page directive: invalid value for import

    我的项目原来用的tomcat版本是apache-tomcat-7.0.53,后来为了安全原因将版本升至\apache-tomcat-7.0.57,发现有的jsp页面出现下面的异常: java.lang ...

  2. 百度2017春招<度度熊回家问题>

    题目: 一个数轴上共有N个点,第一个点的坐标是度度熊现在位置,第N-1个点是度度熊的家.现在他需要依次的从0号坐标走到N-1号坐标.但是除了0号坐标和N-1号坐标,他可以在其余的N-2个坐标中选出一个 ...

  3. Crypt加密函数简介(C语言)

    定义函数 char * crypt (const char *key,const char * salt); 函数说明 crypt是个密码加密函数,它是基于Data Encryption Standa ...

  4. webuploader插件使用分析

    大致架构: 前端:html5+ajax 后端:java (struts框架相关) 碰到问题: 后台coder给我提供一个接口./file/uploader.do?upFile=?,让我上传文件对应up ...

  5. Web前端开发最佳实践(2):前端代码重构

    前言 代码重构是业内经常讨论的一个热门话题,重构指的是在不改变代码外部行为的情况下进行源代码修改,所以重构之前需要考虑的是重构后如何才能保证外部行为不改变.对于后端代码来说,可以通过大量的自动化测试来 ...

  6. 飘窗原生js效果

    css: .close { width: 30px; height: 20px; background: white; position: absolute; right: 0; top: 0; z- ...

  7. bzoj 1497 最小割

    思路:最小割好难想啊,根本想不到.. S -> 用户群 = c[ i ] 基站 -> T = p[ i ] 用户群 -> a[ i ] = inf 用户群 -> b[ i ] ...

  8. 【ASP.NET MVC】Ajax提交表单

    下面这段代码主要有几个特点: 1.Ajax提交表单 2.表单中有一个<input type="file"/> 3.当选择完图片后,利用AJAX提交表单,并在执行成功后返 ...

  9. 主流PHP框架性能评测 (引用)

    主要涉及到的框架有 CodeIgniter 老品牌易用性框架yaf 鸟哥用c写的php扩展,高性能框架yii 自动生成代码(gii)laravel 号称最优雅的框架swoole framework 支 ...

  10. Windows环境上装在VM,VM安装CentOS7

    1.下载VM并且安装 VM下载地址:https://www.vmware.com/products/workstation-pro.html 来自百度经验的的一个密钥(VMware Workstati ...