【C#】线程协作式取消
Microsoft .Net Framework 提供了一个标准的取消操作的模式。这个模式是协作式的,意味着你想取消的操作必须显示地支持取消。
CLR为我们提供了两个类:
System.Threading.CancellationTokenSource
System.Threading.CancellationToken
CancellationToken实例是一个轻量级的值类型,因为它包含单个私有字段:CancellationTokenSource的一个引用。在一个计算限制操作的循环中,可以定时调用CancellationToken的IsCancellationRequested属性,了解循环是否应该提前终止,进而终止计算机限制的操作。
我附上我常用代码:
CancellationTokenSource cancel=new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
while (!cancel.IsCancellationRequested)
{
//do something
}
}, cancel.Token);// cancel.Token->CancellationToken
//取消操作
cancel.Cancel();
cancel.Dispose();
cancel=null;
如果用到线程池,也可以使用这个类
public void main()
{
var cancel=new CancellationTokenSource();
ThreadPool.QueueUserWorkItem(_ =>
{
while (!cancel.IsCancellationRequested)
{
//do something
}
}); Thread.Sleep( * );//为了让循环多做些时间
cancel.Cancel();
cancel.Dispose();
}
这个类还有一个很好的地方,可以在自定义回调函数,在调用Cancel方法的时候使用。这个我们需要用到CancellationToken里面的Register方法(也就是new CancellationTokenSource().Token.Register(()=>{})),并且可以给一个Token多次注册,按照倒序执行。
var cancel = new CancellationTokenSource();
cancel.Token.Register(() =>
{
MessageBox.Show("Register3");
});
cancel.Token.Register(() =>
{
MessageBox.Show("Register");
});
cancel.Token.Register(() =>
{
MessageBox.Show("Register1");
});
cancel.Token.Register(() =>
{
MessageBox.Show("Register2");
});
弹出顺序:Register2,Register1,Register,Register3
如果想注销注册的回调函数,需要用到CancellationTokenRegistration(这个在调用Register的时候就会返回),附代码:
CancellationTokenRegistration registration = cancel.Token.Register(() =>
{
MessageBox.Show("Register2");
});
registration.Dispose();//这里可以取消
取消以后再跑,就只会弹出另外三个,还是倒序。
最后,可通过链接另一组CancellationTokenSource来新建一个CancellationTokenSource对象,任何链接的CancellationTokenSource被取消,这个新的CancellationTokenSource对象就会自动被取消,附代码:
public static void Go()
{
var cts1 = new CancellationTokenSource();
cts1.Token.Register(() => Console.WriteLine("cts1 canceled")); var cts2 = new CancellationTokenSource();
cts2.Token.Register(() => Console.WriteLine("cts2 canceled")); var linkedcts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
linkedcts.Token.Register(() => Console.WriteLine("linkedcts canceled")); cts2.Cancel(); Console.WriteLine("cts1:{0} cts2:{1} linkedcts:{2}",
cts1.IsCancellationRequested, cts2.IsCancellationRequested, linkedcts.IsCancellationRequested);
}

由于cts2对象被取消了,所以linkedcts自动被取消,这里CancellationTokenSource.CreateLinkedTokenSource 有一个重载是params CancellationToken[], 理论上说,无论加多少个CancellationToken对象都是可以的。
【C#】线程协作式取消的更多相关文章
- 协作式取消 CancellationTokenSource
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C#协作试取消线程
https://segmentfault.com/q/1010000017109927using System; using System.Collections.Generic; using Sys ...
- 第41天学习打卡(死锁 Lock synchronized与Lock的对比 线程协作 使用线程池)
死锁 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形.某一个同步块同时拥有"两个以上对象的锁"时 ...
- 基于 Java 2 运行时安全模型的线程协作--转
在 Java 2 之前的版本,运行时的安全模型使用非常严格受限的沙箱模型(Sandbox).读者应该熟悉,Java 不受信的 Applet 代码就是基于这个严格受限的沙箱模型来提供运行时的安全检查.沙 ...
- java线程系列之三(线程协作)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...
- GPU编程自学5 —— 线程协作
深度学习的兴起,使得多线程以及GPU编程逐渐成为算法工程师无法规避的问题.这里主要记录自己的GPU自学历程. 目录 <GPU编程自学1 -- 引言> <GPU编程自学2 -- CUD ...
- JAVA并发-线程协作
这段时间有点忙,技术博客更新的比较少,今天更新一下相关并发的常用线程协作的类吧. ExecutorService 线程池,用于创造和复用线程,他有几种模式. 我举一个自定义线程池数量的例子如下 Exe ...
- CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”
在GPU并行编程中,一般情况下,各个处理器都需要了解其他处理器的执行状态,在各个并行副本之间进行通信和协作,这涉及到不同线程间的通信机制和并行执行线程的同步机制. 共享内存"__share_ ...
- Java多线程之线程协作
Java多线程之线程协作 一.前言 上一节提到,如果有一个线程正在运行synchronized 方法,那么其他线程就无法再运行这个方法了.这就是简单的互斥处理. 假如我们现在想执行更加精确的控制,而不 ...
随机推荐
- 打包时Xcode报:此证书的签发者无效Missing iOS Distribution signing identity
问题描述 今天准备打包上传AppStore,结果Xcode报以下错误:Missing iOS Distribution signing identity for XXXXXX 查看证书后发现,Deve ...
- 通过lua获取nginx的内置变量,通过这些变量做些逻辑的处理
Nginx提供了很多内置的变量,如: $arg_PARAMETER 这个变量包含在查询字符串时GET请求PARAMETER的值. $args 这个变量等于请求行中的参数. $binary_remote ...
- Aspose转PDF时乱码问题的解决
主要原因是服务器上一般安装的字体都是有限的,而我们日常生活工作中总是喜欢用一些比较特别的字体,比如宋体GB2312,这时候如果用Aspose转PDF就会出现乱码,解决方法也比较简单,把本地的特殊字体拷 ...
- Crystal Reports 支持的纸张种类
DefaultPaperSize Paper10x14 254 x 355.6 mm Paper11x17 279.4 x 431.8 mm PaperA3 A3 ?,297 x 420 mm Pap ...
- ArcGIS与SuperMap的使用比较(1)
用了超过6年的超图产品了,因此对超图的很多特性比较熟悉,去年开始接触ARCGIS,并用来研发了一些新产品,因此对于两个GIS平台有些感受,记录如下: 比较版本:ARCGIS10.1与SuperMap ...
- 15.6.6-sql字符串组装技巧
组装sql字符串,丢给exec sp_executesql执行 exec sp_executesql N'exec sp_executesql N''select * from TESTTEST.db ...
- JQuery 表格拖动调整列宽效果
类似于桌面程序中的表格拖动表头的效果,当鼠标停留在表头边框线上时,鼠标会变成表示左右拖动的形状,接着拖动鼠标,会在表格中出现一条随鼠标移动的竖线,最后放开鼠标,表格列宽会被调整.最近比较空闲,便自己动 ...
- 初探Stage3D(三) 深入研究透视投影矩阵
关于本文 本文主要讲解从数学的角度如何推导出Stage3D中用到的两个投影矩阵 perspectiveLH public function perspectiveLH(width:Number,hei ...
- JavaScript ---属性
获取属性 可以通过点(.)或方挂号([])运算符来获取属性的值. 对于点(.)来说,右侧必须是一个以属性名称命名的简单标识符.对于[]来说,方挂号内必须是一个计算结果为字符串的表达式. var aut ...
- [LeetCode] 桶排序的特殊解,例 Sort Color
Sort Colors Given an array with n objects colored red, white or blue, sort them so that objects of t ...