CancellationTokenSource 类

定义

通知 CancellationToken,告知其应被取消。

public ref class CancellationTokenSource : IDisposable
public ref class CancellationTokenSource sealed : IDisposable
public class CancellationTokenSource : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public sealed class CancellationTokenSource : IDisposable
[System.Runtime.InteropServices.ComVisible(false)]
public class CancellationTokenSource : IDisposable
type CancellationTokenSource = class
    interface IDisposable
[<System.Runtime.InteropServices.ComVisible(false)>]
type CancellationTokenSource = class
    interface IDisposable
Public Class CancellationTokenSource
Implements IDisposable
Public NotInheritable Class CancellationTokenSource
Implements IDisposable
继承
CancellationTokenSource
属性
实现

示例

以下示例使用随机数生成器模拟一个数据收集应用程序,该应用程序从 11 个不同仪器中读取 10 个整型值。 值为零表示一个仪器的测量失败,在这种情况下,应取消操作,并且不应计算总体平均值。

为了处理操作的可能取消,该示例实例化了一个 CancellationTokenSource 对象,该对象生成传递给对象的 TaskFactory 取消标记。 对象 TaskFactory 又将取消令牌传递给负责收集特定仪器读数的每个任务。 TaskFactory.ContinueWhenAll<TAntecedentResult,TResult>(Task<TAntecedentResult>[], Func<Task<TAntecedentResult>[],TResult>, CancellationToken)调用 方法可确保仅在成功收集所有读数后计算平均值。 如果任务因已取消而尚未完成,则对 方法的 TaskFactory.ContinueWhenAll 调用将引发异常。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      // Define the cancellation token.
      CancellationTokenSource source = new CancellationTokenSource();
      CancellationToken token = source.Token;

      Random rnd = new Random();
      Object lockObj = new Object();
      
      List<Task<int[]>> tasks = new List<Task<int[]>>();
      TaskFactory factory = new TaskFactory(token);
      for (int taskCtr = 0; taskCtr <= 10; taskCtr++) {
         int iteration = taskCtr + 1;
         tasks.Add(factory.StartNew( () => {
           int value;
           int[] values = new int[10];
           for (int ctr = 1; ctr <= 10; ctr++) {
              lock (lockObj) {
                 value = rnd.Next(0,101);
              }
              if (value == 0) { 
                 source.Cancel();
                 Console.WriteLine("Cancelling at task {0}", iteration);
                 break;
              }   
              values[ctr-1] = value; 
           }
           return values;
        }, token));   
      }
      try {
         Task<double> fTask = factory.ContinueWhenAll(tasks.ToArray(), 
         (results) => {
            Console.WriteLine("Calculating overall mean...");
            long sum = 0;
            int n = 0; 
            foreach (var t in results) {
               foreach (var r in t.Result) {
                  sum += r;
                  n++;
               }
            }
            return sum/(double) n;
         } , token);
         Console.WriteLine("The mean is {0}.", fTask.Result);
      }   
      catch (AggregateException ae) {
         foreach (Exception e in ae.InnerExceptions) {
            if (e is TaskCanceledException)
               Console.WriteLine("Unable to compute mean: {0}", 
                  ((TaskCanceledException) e).Message);
            else
               Console.WriteLine("Exception: " + e.GetType().Name);
         }
      }
      finally {
         source.Dispose();
      }
   }
}
// Repeated execution of the example produces output like the following:
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 10
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 5.29545454545455.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 6
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 4.97363636363636.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 5
//       Unable to compute mean: A task was canceled.
//       
//       Cancelling at task 4
//       Unable to compute mean: A task was canceled.
//       
//       Calculating overall mean...
//       The mean is 4.86545454545455.
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      ' Define the cancellation token.
      Dim source As New CancellationTokenSource()
      Dim token As CancellationToken = source.Token

      Dim lockObj As New Object()
      Dim rnd As New Random

      Dim tasks As New List(Of Task(Of Integer()))
      Dim factory As New TaskFactory(token)
      For taskCtr As Integer = 0 To 10
         Dim iteration As Integer = taskCtr + 1
         tasks.Add(factory.StartNew(Function()
                                       Dim value, values(9) As Integer
                                       For ctr As Integer = 1 To 10
                                          SyncLock lockObj
                                             value = rnd.Next(0,101)
                                          End SyncLock
                                          If value = 0 Then 
                                             source.Cancel
                                             Console.WriteLine("Cancelling at task {0}", iteration)
                                             Exit For
                                          End If   
                                          values(ctr-1) = value 
                                       Next
                                       Return values
                                    End Function, token))   
         
      Next
      Try
         Dim fTask As Task(Of Double) = factory.ContinueWhenAll(tasks.ToArray(), 
                                                         Function(results)
                                                            Console.WriteLine("Calculating overall mean...")
                                                            Dim sum As Long
                                                            Dim n As Integer 
                                                            For Each t In results
                                                               For Each r In t.Result
                                                                  sum += r
                                                                  n+= 1
                                                               Next
                                                            Next
                                                            Return sum/n
                                                         End Function, token)
         Console.WriteLine("The mean is {0}.", fTask.Result)
      Catch ae As AggregateException
         For Each e In ae.InnerExceptions
            If TypeOf e Is TaskCanceledException
               Console.WriteLine("Unable to compute mean: {0}", 
                                 CType(e, TaskCanceledException).Message)
            Else
               Console.WriteLine("Exception: " + e.GetType().Name)
            End If   
         Next
      Finally
         source.Dispose()
      End Try                                                          
   End Sub
End Module
' Repeated execution of the example produces output like the following:
'       Cancelling at task 5
'       Unable to compute mean: A task was canceled.
'       
'       Cancelling at task 10
'       Unable to compute mean: A task was canceled.
'       
'       Calculating overall mean...
'       The mean is 5.29545454545455.
'       
'       Cancelling at task 4
'       Unable to compute mean: A task was canceled.
'       
'       Cancelling at task 5
'       Unable to compute mean: A task was canceled.
'       
'       Cancelling at task 6
'       Unable to compute mean: A task was canceled.
'       
'       Calculating overall mean...
'       The mean is 4.97363636363636.
'       
'       Cancelling at task 4
'       Unable to compute mean: A task was canceled.
'       
'       Cancelling at task 5
'       Unable to compute mean: A task was canceled.
'       
'       Cancelling at task 4
'       Unable to compute mean: A task was canceled.
'       
'       Calculating overall mean...
'       The mean is 4.86545454545455.

注解

从.NET Framework 4 开始,.NET Framework使用统一模型来协同取消涉及两个对象的异步或长时间运行的同步操作:

用于实现协作取消模型的常规模式是:

有关详细信息,请参阅托管线程中的取消

重要

此类型实现 IDisposable 接口。 使用完 类型的实例后,应直接或间接释放它。 若要直接释放类型,请在 try/finally 块中调用其 Dispose 方法。 若要间接释放类型,请使用 using(在 C# 中)或 Using(在 Visual Basic 中)等语言构造。 有关详细信息,请参阅 IDisposable 接口主题中的“使用实现 IDisposable 的对象”一节。

构造函数

CancellationTokenSource()

初始化 CancellationTokenSource 类的新实例。

CancellationTokenSource(Int32)

初始化 CancellationTokenSource 类的新实例,在指定的延迟(以毫秒为单位)后将被取消。

CancellationTokenSource(TimeSpan)

初始化 CancellationTokenSource 类的新实例,在指定的时间跨度后将被取消。

CancellationTokenSource(TimeSpan, TimeProvider)

初始化 类的新实例, CancellationTokenSource 该实例将在指定的 TimeSpan之后取消。

属性

IsCancellationRequested

获取是否已请求取消此 CancellationTokenSource

Token

获取与此 CancellationToken 关联的 CancellationTokenSource

方法

Cancel()

传达取消请求。

Cancel(Boolean)

如果出现异常,传达取消请求,并指定是否应处理其余回调和可取消操作。

CancelAfter(Int32)

在指定的毫秒数后计划对此 CancellationTokenSource 的取消操作。

CancelAfter(TimeSpan)

在指定的时间跨度后计划对此 CancellationTokenSource 的取消操作。

CancelAsync()

异步传达取消请求。

CreateLinkedTokenSource(CancellationToken)

创建当提供的标记处于已取消状态时将处于已取消状态的 CancellationTokenSource

CreateLinkedTokenSource(CancellationToken, CancellationToken)

创建一个将在任何源标记处于取消状态时处于取消状态的 CancellationTokenSource

CreateLinkedTokenSource(CancellationToken[])

创建一个将在在指定的数组中任何源标记处于取消状态时处于取消状态的 CancellationTokenSource

Dispose()

释放 CancellationTokenSource 类的当前实例所使用的所有资源。

Dispose(Boolean)

释放 CancellationTokenSource 类使用的非托管资源,并可以选择释放托管资源。

Equals(Object)

确定指定对象是否等于当前对象。

(继承自 Object)
GetHashCode()

作为默认哈希函数。

(继承自 Object)
GetType()

获取当前实例的 Type

(继承自 Object)
MemberwiseClone()

创建当前 Object 的浅表副本。

(继承自 Object)
ToString()

返回表示当前对象的字符串。

(继承自 Object)
TryReset()

尝试将 重置 CancellationTokenSource 为用于不相关操作的 。

适用于

线程安全性

的所有公共成员和受保护成员 CancellationTokenSource 都是线程安全的,并且可以从多个线程同时使用,但 除外 Dispose(),只有在对象上的 CancellationTokenSource 所有其他操作都已完成时才能使用。

另请参阅