.Net4.0并行库介绍——Cancellation Framework
在.net 4.0中,引入了一个新的类CancellationToken,这个类基本上集成了我们各种常用的取消方式,在并发任务中非常有用。
同步模式下的取消:
一种比较常见的需要支持取消功能的的是一些比较耗时的分段操作:如视频转换,网络下载等,这种方式下的取消机制如下:
- 建立一个标记位,表示该操作是否已经取消
- UI线程在获取到取消事件后,置标记位为true
- 耗时的操作线程里,没进行一小段操作之后查询该标记位,如果为true则主动退出。
使用方式如下:
; ; i < ; i++) { ; j < ; j++) { total++; } if (token.IsCancellationRequested) { // observe cancellation throw new OperationCanceledException(token); // acknowledge cancellation } } return total; }
异步模式下的取消
另外一种常见的方式是在一些异步操作中,往往不能主动释放,只能等待异步操作回调的时候才能操作结果。此时一般取消方法如下:
- 任务线程注册异步操作完成的回调函数,开始异步操作。
- UI线程接受取消指令,置取消标记位,并主动执行回调函数
- 回调函数中通过取消标记位判断该任务是已经完成还是被取消的,并执行相关析构操作。
使用方式如下:
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的更多相关文章
- .Net4.0并行库介绍——Task
Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务.对于将一个任务放进线程池 ThreadPool.QueueUserWorkItem(A); 这段代码用Task来实现 ...
- 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). 其次是 ...
- C#多线程编程系列(五)- 使用任务并行库
目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...
- .Net4.0 任务(Task)[转]
.Net4.0 任务(Task) 任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks ...
- Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) JAVA日志的前世今生 .NET MVC采用SignalR更新在线用户数 C#多线程编程系列(五)- 使用任务并行库 C#多线程编程系列(三)- 线程同步 C#多线程编程系列(二)- 线程基础 C#多线程编程系列(一)- 简介
Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) 一.前言 由于本篇文章较长,所以下面给出内容目录方便跳转阅读,当然也可以用博客页面最右侧的文章目录导航栏进行跳转查阅. 一.前言 ...
- C#多线程开发-任务并行库04
你好,我是阿辉. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了使用线程的细节,使我们可以专心处理程序逻辑, ...
- C#当中的多线程_任务并行库(上)
复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...
- Android开发中用到的框架、库介绍
Android开发中用到的框架介绍,主要记录一些比较生僻的不常用的框架,不断更新中...... 网路资源:http://www.kuqin.com/shuoit/20140907/341967.htm ...
- .Net4.0 任务(Task)
任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks 命名空间下任务相关类一览: 类 ...
随机推荐
- Linux系统调优及安全设置
1.关闭SELinux #临时关闭 setenforce 0 #永久关闭 vim /etc/selinux/config SELINUX=disabled 2.设定运行级别为3 #设定运行级别 vim ...
- Java的BIO,NIO,AIO
Java中的IO操作可谓常见.在Java的IO体系中,常有些名词容易让人困惑不解.为此,先通俗地介绍下这些名词. 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同 ...
- navigator.geolocation详解
https://blog.csdn.net/qq_27626333/article/details/51815467 PositionOptions: JSON对象,监听设备位置信息参数 naviga ...
- LSTM及其变种及其克服梯度消失
本宝宝又转了一篇博文,但是真的很好懂啊: 写在前面:知乎上关于lstm能够解决梯度消失的问题的原因: 上面说到,LSTM 是为了解决 RNN 的 Gradient Vanish 的问题所提出的.关于 ...
- Linux下快速查找文件
1 locate 查找内容.查找数据库,updatedb命令更新数据库 2 which 命令 3 find 路径 -name 查找内容.find命令会磁盘查找,比较耗时. 4 grep 查找内容一般为 ...
- Java显式锁学习总结之三:AbstractQueuedSynchronizer的实现原理
概述 上一篇我们讲了AQS的使用,这一篇讲AQS的内部实现原理. 我们前面介绍了,AQS使用一个int变量state表示同步状态,使用一个隐式的FIFO同步队列(隐式队列就是并没有声明这样一个队列,只 ...
- 简单优化:Zipalign
Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化.在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率.因此,这种方式 ...
- linux中的vim 编辑一行内容,如何使光标快速移动到行首和行尾以及行中间某处啊?
光标定位G 移至行行首nG 移至第n行行首n+ 移n行行首n- 移n行行首n$ 移n行(1表示本行)行尾0 所行行首$ 所行行尾^ 所行首字母h,j,k,l 左移移移右移H 前屏幕首行行首M 屏幕显示 ...
- Scrapy 增加随机请求头 user_agent
原文: 为什么要增加随机请求头:更好地伪装浏览器,防止被 Ban. 如何在每次请求时,更换不同的 user_agent,Scrapy 使用 Middleware 即可 Spider 中间件 (Midd ...
- ssh连接远程主机免密登入
核心思想: 1.本地主机生成公钥私钥,私钥自己存着,公钥传到远程主机.ssh文件夹下authorized_keys文件(默认是这个,用追加的方式) 2.本地连接远程主机,公私钥对上就可以免密登入了. ...