.Net4.0并行库介绍——Cancellation Framework
在.net 4.0中,引入了一个新的类CancellationToken,这个类基本上集成了我们各种常用的取消方式,在并发任务中非常有用。
同步模式下的取消:
一种比较常见的需要支持取消功能的的是一些比较耗时的分段操作:如视频转换,网络下载等,这种方式下的取消机制如下:
- 建立一个标记位,表示该操作是否已经取消
- UI线程在获取到取消事件后,置标记位为true
- 耗时的操作线程里,没进行一小段操作之后查询该标记位,如果为true则主动退出。
使用方式如下:
EventHandler externalEvent; void Example1() { CancellationTokenSource cts = new CancellationTokenSource(); externalEvent += (sender, obj) => { cts.Cancel(); }; //wire up an external requester try { int val = LongRunningFunc(cts.Token); } catch (OperationCanceledException) { //cleanup after cancellation if required... } }
private static int LongRunningFunc(CancellationToken token) { int total = 0; for (int i = 0; i < 1000; i++) { for (int j = 0; j < 1000; 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. }
最后我们再来一个并发查询时取消的例子:
private void RunQuery() { int[] data = { 1, 2, 3 }; 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还是非常实用的,通过它可以更有效的简化及规范的使用各种取消的操作方式,由于我也只会皮毛,在这里也只是介绍了它的基本用法,在后续的学习和应用中将继续进一步介绍。
转载于:https://www.cnblogs.com/zjoch/p/3508301.html
.Net4.0并行库介绍——Cancellation Framework相关推荐
- .NET4.0并行计算技术基础(8)
说明: 要想看懂本系列文章,需要您对.NET多线程开发有基本的了解.我在新书<面向对象的艺术 --.NET Framework 4.0技术剖析与应用>(暂名)中花了近200页的篇幅来介绍. ...
- .Net 4.0并行库实用性演练[1]
自VS2010发布近半年了,虽然整天想学习新东西,要更新到自己时,发现原来自己基本也很懒,2008还没用上多久呢,无奈被2010了.用了几天,IDE模样还是和05.08差不多,加了些小特性,以后慢慢体 ...
- Net 4.0并行库实用性演练
引言 随着CPU多核的普及,编程时充分利用这个特性越显重要.上篇首先用传统的嵌套循环进行数组填充,然后用.NET 4.0中的System.Threading.Tasks提供的Parallel Clas ...
- .Net并行库介绍——Task(1)
Task和ThreadPool的功能类似,可以用来创建一些轻量级的并行任务.对于将一个任务放进线程池 ThreadPool.QueueUserWorkItem(A); 这段代码用Task来实现 ...
- .Net 4.0并行库实用性演练
前面说在练习Parallel时,发现另有乾坤,是这样的代码: 代码 static IEnumerable<Person> testFill() { var list =new List&l ...
- 详细介绍百度ERNIE 2.0:A Continual Pre-Training Framework for Language Understanding
系列阅读: 详细介绍百度ERNIE1.0:Enhanced Representation through Knowledge Integration 详细介绍百度ERNIE 2.0:A Continu ...
- Windows7安装Framework .NET4.0失败
安装CAD2007 CAD2014等需要Framework .NET4.0始终无法安装成功,总是提示 "安装时发生严重错误",看log发现返回"Installation ...
- iOS架构-静态库.a 和.framework的区别(0)
原文网址:https://my.oschina.net/kaqijiang/blog/649632 一.什么是库? 库是共享程序代码的方式. 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存 ...
- C#多线程开发-任务并行库
你好,我是阿辉. 正文共2090字,预计阅读时间:6min. 之前学习了线程池,知道了它有很多好处. 使用线程池可以使我们在减少并行度花销时节省操作系统资源.可认为线程池是一个抽象层,其向程序员隐藏了 ...
最新文章
- Android Studio 的安装笔记
- mvc ajax教程,MVC3----AJAX辅助方法
- SpringMVC接收checkbox传值
- C语言 满分代码:L1-043 阅览室 (20分)(解题报告)
- google天气预报接口_将天气预报添加到谷歌浏览器
- python调用带参函数_Python | 带有示例的函数调用类型
- 建立丰富多彩的toast的简单实例
- 线程销毁_多线程(2)-Java高级知识(9)
- eclipse一些实用小技巧
- 【学习笔记】尚硅谷大数据项目之Flink实时数仓---DWD和DIM
- wgs84坐标系拾取工具_Wgs84坐标系转换为gcj02坐标系及bd09坐标系的验证
- 细粒度分类:Hierarchical Bilinear Pooling(HBP),分级双线性池化(一)
- SpringBoot+zxing批量生成二维码_南国
- 基于安卓的共享自习室的设计与实现
- 卸载重装Ubuntu22.04双系统
- 最短Hamilton路径(哈密顿图,状压dp)
- BOM中的location对象
- 【菜菜的sklearn课堂笔记】决策树-分类树
- 安卓使用connectbot连接centos云服务器
- Ecshop 表结构 字段说明
热门文章
- python装饰器深度讲解_python核心知识讲解,干货!!!
- matlab循环标注,for循环
- Linux 内核网络协议栈运行原理
- 【必看】运维是“越老越吃香“的职业?
- 如何发现 Kubernetes 中服务和工作负载的异常
- java hook 框架_hook框架-frida简单使用模板以及frida相关接口
- linux系统编译安装mysql_Linux下编译安装MySQL
- git reset 怎么还原_git reset –hard后的恢复操作
- sql截去最后一位_sql 取最后一条记录
- chart控件做实时曲线显示_用PyQt5.QtChart实现动态曲线图