zoukankan      html  css  js  c++  java
  • 《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. }




  • 相关阅读:
    robotframework学习笔记七:robotframework的数据驱动模式
    robotframework学习笔记六:Set Variable If 关键字的使用
    robotframework学习笔记五:robotframework控制流if和for
    C# BS方向 该如何规划学习?【学习路线指南】
    毕业四年,我当初是如何走上编程这条路的!
    设计模式之备忘录
    设计模式之中介者
    设计模式之迭代器
    设计模式之命令模式
    nginx 499 错误解决
  • 原文地址:https://www.cnblogs.com/qianzi067/p/5815567.html
Copyright © 2011-2022 走看看