C# 应用 - 多线程 4) Task cancel

1. 操作取消

1.1 步骤

  • 实例化 CancellationTokenSource 对象,该对象管理取消通知并将其发送给单个取消标记
  • 将 CancellationTokenSource.Token 属性返回的标记传递给每个侦听取消的任务或线程
  • 为每个任务或线程提供响应取消的机制
    if (token.IsCancellationRequested)
  • 调用 CancellationTokenSource.Cancel 方法以提供取消通知

1.2 代码示例

using System;
using System.Threading;

public class Example
{
   public static void Main()
   {
      CancellationTokenSource cts = new CancellationTokenSource();

      ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), cts.Token);
      Thread.Sleep(2500);

      cts.Cancel();
      Console.WriteLine("Cancellation set in token source...");
      
      Thread.Sleep(2500);
      cts.Dispose();
   }

   static void DoSomeWork(object obj)
   {
      CancellationToken token = (CancellationToken)obj;

      for (int i = 0; i < 100000; i++) 
      {
         if (token.IsCancellationRequested)
         {
            Console.WriteLine("在 i 为 {0} 时, 监听到 cancellation", i);
            break;
         }
         Thread.SpinWait(500000);
      }
   }
}
// 上诉例子输出:
//    Cancellation set in token source...
//    In iteration 1935, cancellation has been requested...

2. 对象取消

类似于事件的订阅和触发

using System;
using System.Threading;

class CancelableObject
{
   public string id;

   public CancelableObject(string id)
   {
      this.id = id;
   }

   public void Cancel()
   {
      Console.WriteLine("Object {0} Cancel callback", id);
   }
}

public class Example
{
   public static void Main()
   {
      CancellationTokenSource cts = new CancellationTokenSource();
      CancellationToken token = cts.Token;

      var obj1 = new CancelableObject("1");
      var obj2 = new CancelableObject("2");
      
      token.Register(() => obj1.Cancel());
      token.Register(() => obj2.Cancel());

      cts.Cancel();
      cts.Dispose();
   }
}
// 上诉将输出:
//    Object 2 Cancel callback
//    Object 1 Cancel callback
上一篇:[NOI2014]动物园


下一篇:洛谷P2305 [NOI2014]购票 [DP,树状数组]