最近在读CLR via C#,线程章节中有一个关于“协作式取消和超时”。例子代码如下:
static void Main(string[] args) { //第一段处理线程取消的操作方式,根据书上的例子P616 CancellationTokenSource cts = new CancellationTokenSource(); ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 20)); Console.ReadKey(); cts.Cancel(); //第二段处理线程取消的操作方式,自己编写的函数 int c = 10; ThreadPool.QueueUserWorkItem(o => Count2(20,ref c )); Console.ReadKey(); c = 100; cts.Cancel(); Console.ReadKey(); } private static void Count(CancellationToken token, int v) { for (int n = 0; n < v; n++) { if (token.IsCancellationRequested) { Console.WriteLine("Count is cancelled"); break; } Console.WriteLine(n); Thread.Sleep(200); } Console.WriteLine("count is done"); } private static void Count2(int v, ref int c) { for (int n = 0; n < v; n++) { if (c!= 10) { Console.WriteLine("Count is cancelled"); break; } Console.WriteLine(n); Thread.Sleep(200); } Console.WriteLine("count2 is done"); }
根据注释区分的两段代码流程都可以实现:在线程运行的过程中,通过手动输入任意字符使线程取消操作。
所有有个疑问是CancellationTokenSource这个类有什么特殊的含义?仅仅是官方推荐的一种用法专门定义了这个类,还是有其他用法?还是我的理解不到位。
希望有经验的朋友能分享,谢谢。
在Count
中你可以通过token.IsCancellationRequested
知道线程被取消了,进行相应的处理
在Count2
中你无法准确知道线程被取消了
首先,感谢你的回复。
还是有点不理解:
对于count函数的线程,我通过token.IsCancellationRequested来判断是否线程需要被取消,从而退出操作;对于count2函数的线程,我通过引用地址的值来判断。
从主线程main函数中看,我可以根据token.IsCancellationRequested来判断第一个是否结束,也可以根据变量c的值来判断第二个是否结束。
实际两个线程都没有技术,而是根据传入的参数进行判断。对主线程而言,也没有前置中止线程,只是改变传入参数的对象数值来告诉线程让线程自己判断结束。所以我不太理解这个CancellationTokenSource有什么特别的用意。
不好意思最后一段有一些打字错误,修正如下:
实际两个线程都没有真正结束,而是根据传入的参数进行判断是否不继续执行。对主线程而言,也没有强制中止线程,只是改变传入参数的对象数值来告诉线程让线程自己判断结束。所以我不太理解这个CancellationTokenSource有什么特别的用意。
@百里景云: 如果 Count() 中在进行一个很耗 CPU 的工作,有 CancellationTokenSource ,可以在发生取消操作时立即停止很耗 CPU 的工作
@百里景云: 推荐园子里的一篇博文 多核时代 .NET Framework 4 中的并行编程3---任务并行库之Task (下)