【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 方法,那么其他线程就无法再运行这个方法了.这就是简单的互斥处理. 假如我们现在想执行更加精确的控制,而不 ...
随机推荐
- js获取gridview模板列中textbox行列的值
下面一个例子:在gridview中第一列输入数值,第二列输入数值,点击第三列的时候进行计算 求和,如果不符合标记为红色字体. 如图: 代码 : <html xmlns="http:// ...
- C# 模拟鼠标(mouse_event)
想必有很多人在项目开发中可能遇见需要做模拟鼠标点击的小功能,很多人会在 百度过后采用mouse_event这个函数,不过我并不想讨论如何去使用mouse_event 函数怎么去使用,因为那没有多大意义 ...
- config中自定义配置
1. 定义自己的KeyValue <section name="TestKeyValue" type="System.Configuration.NameValue ...
- PInvoke在 2.0 3.0的时候正常 升级到4.0后出错。
方法1: 设置 CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl,但是我设置了也是出错.换一个con ...
- MSSQL获得表的字段名称及其参数
SELECT ColumnsName = c.name, [Description] = ex.value, ColumnType = t.name, [Length]=c.max_length FR ...
- 十家国内知名的EDM服务提供商
国内的EDM服务商多若繁星.下面博主为大家介绍十家国内知名的EDM服务提供商. 一.Webpower 威勃庞尔. 官方网站是:www.webpower.asia.作为全球领先的邮件营销解决方案提供商, ...
- asp.net mvc 利用过滤器进行网站Meta设置
过去几年都是用asp.net webform进行开发东西,最近听说过时了,同时webform会产生ViewState(虽然我已经不用ruanat=server的控件好久了 :)),对企业应用无所谓,但 ...
- char str[]和char *str的区别
1.http://blog.csdn.net/szchtx/article/details/10396149 char ss[]="C++"; ss[0]='c'; ...
- c# double保留2位小数
/ (endIndex - startIndex); interval = Math.Round(interval , );
- Visual Studio与Eclipse与IntelliJ快捷键对比