《CLR via C#》之线程处理——协作式取消和超时

《CLR via C#》之线程处理——协作式取消和超时

《CLR via C#》之线程处理——协作式取消和超时
协作式取消和超时

协作式取消和超时

创建协作式取消步骤:

  1. 首先创建一个System.Threading.CancellationTokenSource对象。
  1. public sealed class CancellationTokenSource : IDisposable
  2. {
  3. // 一个引用类型
  4. public void Dispose(); // 释放资源(比如WaitHandle)
  5. public Boolean IsCancellationRequested { get; }
  6. public CancellationToken Token { get; }//通过这个属性获得Token并传递给操作。
  7. public void Cancel(); // 内部调用Cancel并传递false
  8. public void Cancel(Boolean throwOnFirstException);
  9. ...
  10. }
  1. 通过CancellationTokenSource.Token属性获得一个或多个CancellationToken,并传递给操作。
  1. public struct CancellationToken
  2. {
  3. // 一个值类型
  4. public static CancellationToken None { get; }
  5. public Boolean IsCancellationRequested{ get; } // 由非通过Task调用的操作调用
  6. public void ThrowIfCancellationRequested(); // 由通过Task调用的操作调用
  7. //CancellationTokenSource 取消时,WaitHandle 会收到信号
  8. public WaitHandle WaitHandle { get; }
  9. public Boolean CanBeCanceled { get; } // 很少使用
  10. public CancellationTokenRegistration Register(Action<Object> callback, Object state,
  11. Boolean useSynchronizationContex); // 未列出更简单的重载版本
  12. }
  1. 需要取消的方法中定期查询IsCancellationRequest属性。
  1. internal static class CancellationDemo
  2. {
  3. public static void Go()
  4. {
  5. CancellationTokenSource cts = new CancellationTokenSource();
  6. cts.Token.Register(() => Console.WriteLine("cancel callbace!!!"));
  7. var restration = cts.Token.Register(o => Console.WriteLine("Cancel callback{0}!!!", o), 5, true);
  8. restration.Dispose();
  9. ThreadPool.QueueUserWorkItem(o => Count(cts.Token, 1000));
  10. Console.WriteLine("Press Enter to cancel");
  11. Console.ReadLine();
  12. cts.Cancel();
  13. Console.ReadLine();
  14. }
  15. private static void Count(CancellationToken token, Int32 countTo)
  16. {
  17. for (int count = 0; count < countTo; count++)
  18. {
  19. if (token.IsCancellationRequested)
  20. {
  21. Console.WriteLine("Count is cancelled");
  22. break;
  23. }
  24. Console.WriteLine(count);
  25. Thread.Sleep(200);
  26. }
  27. Console.WriteLine("Count is done");
  28. }
  29. }

PS:如果要执行一个不允许被取消的操作,可以向操作传递CancellationTokenSource.None属性。

  1. 如果需要,可以调用CancellationToken的Register方法,注册取消时的CallBack。可以通过该方法的返回值CallcellationTakenRegistration,调用它的Dispose方法删除注册的回调函数。
  2. 还可以链接另一组CancellationTokenSource来新建一个CancellationTokenSource对象。
  1. var cts1 = new CancellationTokenSource();
  2. cts1.Token.Register(() => Console.WriteLine("cts1 cancelled"));
  3. var cts2 = new CancellationTokenSource();
  4. cts2.Token.Register(() => Console.WriteLine("cts2 canceled"));
  5. //创建一个新的,它在cts1或cts2取消时取消
  6. var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
  7. linkedCts.Token.Register(() => Console.WriteLine("linkedCts canceled"));
  1. 还可以通过CancellationTokenSource的构造器或调用CancelAfter来指定延时时间,到时自动取消。
  1. public sealed class CancellationTokenSource : IDisposable
  2. {
  3. public CancellationTokenSource(Int32 millisecondsDelay);
  4. public CancellationTokenSource(TimeSpan delay);
  5. public void CancelAfter(Int32 millisecondsDelay);
  6. public void CancelAfter(TimeSpan delay);
  7. ...
  8. }

来自为知笔记(Wiz)

时间: 2024-08-02 20:20:24

《CLR via C#》之线程处理——协作式取消和超时的相关文章

线程与线程池以及任务和协商式取消

一.线程 使用System.Threading命名空间下的Thread类即可创建专有线程 var t = new Thread(() => Console.WriteLine("new thread")); 构造函数有如下四个版本 Thread(ThreadStart start); public Thread(ThreadStart start, int maxStackSize); public Thread(ParameterizedThreadStart start);

Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当

JAVA线程间协作:wait.notify.notifyAll

JAVA的进程同步是通过synchronized()来实现的,须要说明的是,JAVA的synchronized()方法相似于操作系统概念中的相互排斥内存块.在JAVA中的Object类型中.都是带有一个内存锁的,在有线程获取该内存锁后.其它线程无法訪问该内存.从而实现JAVA中简单的同步.相互排斥操作. 明确这个原理.就能理解为什么synchronized(this)与synchronized(static XXX)的差别了.synchronized就是针对内存区块申请内存锁,thiskeywo

多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition

Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对

Java多线程之线程的状态以及线程间协作通信导致的状态变换

一:线程的状态以及变化图 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线程创建完成时为新建状态,即new Thread(...),还没有调用start方法时,线程处于新建状态. Runnable:就绪状态,当调用线程的的start方法后,线程进入就绪状态,等待CPU资源.处于就绪状态的线程由Java运行时系统的线程调度程序(thread scheduler)来

thread_线程间协作:wait、notify、notifyAll和Condition

经典模式:生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了.这种互相通信

19、Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对

南邮JAVA程序设计实验4 线程程序设计(指针式时钟)

南邮JAVA程序设计实验4  线程程序设计(指针式时钟) 实验目的: 本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力. 实验内容: 设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动. 实验设计: 主要是控制时针分针秒针的转动度数,这个直接通过坐标的三角函数值求得,线程方面,隔一秒休眠一下,然后通过时分秒的换算关系来改变三个对应指示针在时钟上的位置 实验代码: import java.awt.*;

Java 多线程 :入门(2)- 线程间协作:挂起当前线程(wait)与通知其他线程继续执行(notify\ notifyAll)

首先,之前我理解起来比较混沌的是到底谁是‘锁’这个问题,因为线程间协作的核心就是锁的交换,通过每个线程的“获得锁”与“释放锁”来实现. 锁,也叫“互斥”,是一种机制,通过控制一个对象在一定代码段(或方法内)同时只能被一个线程所访问,来实现所谓的(对于这个特定对象的)“线程安全”. 1.先看一个从网上扒来的最基本款示例,原文 http://www.cnphp6.com/archives/62258,写的很棒很清晰,我这里略微改了一两句: public class TestNotifyByFlag