Поделиться через


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
Атрибуты
Реализации

Примеры

В следующем примере используется генератор случайных чисел для эмуляции приложения сбора данных, которое считывает 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 использует единую модель для совместной отмены асинхронных или длительных синхронных операций, включающих два объекта:

  • CancellationTokenSource Объект, который предоставляет маркер отмены через его Token свойство и отправляет сообщение об отмене путем вызова его Cancel или CancelAfter метода.

  • Объект, указывающий CancellationToken , запрашивается ли отмена.

Общий шаблон реализации модели совместной отмены:

  • Создайте CancellationTokenSource экземпляр объекта, управляющего и отправляющего сообщения об отмене отдельным маркерам отмены.

  • Передайте маркер, возвращаемый свойством CancellationTokenSource.Token каждой задаче или потоку, который прослушивает отмену.

  • CancellationToken.IsCancellationRequested Вызовите метод из операций, получающих маркер отмены. Предоставьте механизм для каждой задачи или потока для реагирования на запрос отмены. Если вы решили отменить операцию, а именно как это сделать, зависит от логики приложения.

  • CancellationTokenSource.Cancel Вызовите метод для предоставления уведомления об отмене. Это задает CancellationToken.IsCancellationRequested свойство для каждой копии маркера trueотмены.

  • Dispose Вызовите метод после завершения работы с CancellationTokenSource объектом.

Дополнительные сведения см. в разделе Отмена в управляемых потоках.

Важный

Этот тип реализует IDisposable интерфейс. Завершив использование экземпляра типа, его следует удалить напрямую или косвенно. Чтобы удалить тип напрямую, вызовите его Dispose метод в блоке try/finally . Чтобы удалить его косвенно, используйте конструкцию языка, например using (в C#) или Using (в Visual Basic). Дополнительные сведения см. в разделе "Использование объекта, реализующего IDisposable" в IDisposable разделе интерфейса.

Конструкторы

Имя Описание
CancellationTokenSource()

Инициализирует новый экземпляр класса CancellationTokenSource.

CancellationTokenSource(Int32)

Инициализирует новый экземпляр класса, который будет отменен после указанной CancellationTokenSource задержки в миллисекундах.

CancellationTokenSource(TimeSpan, TimeProvider)

Инициализирует новый экземпляр CancellationTokenSource класса, который будет отменен после указанного TimeSpan.

CancellationTokenSource(TimeSpan)

Инициализирует новый экземпляр класса, который будет отменен после указанного CancellationTokenSource периода времени.

Свойства

Имя Описание
IsCancellationRequested

Возвращает, запрашивается ли отмена для этого CancellationTokenSource.

Token

Возвращает связанный CancellationToken с этим CancellationTokenSourceобъект.

Методы

Имя Описание
Cancel()

Сообщает запрос на отмену.

Cancel(Boolean)

Сообщает запрос на отмену и указывает, следует ли обрабатывать оставшиеся обратные вызовы и отменяемые операции, если возникает исключение.

CancelAfter(Int32)

Запланирует операцию отмены после CancellationTokenSource указанного числа миллисекунда.

CancelAfter(TimeSpan)

Планирует операцию отмены для этого CancellationTokenSource после указанного интервала времени.

CancelAsync()

Асинхронно передает запрос на отмену.

CreateLinkedTokenSource(CancellationToken, CancellationToken)

Создает объект CancellationTokenSource , который будет находиться в состоянии отмены, когда любой из исходных маркеров находятся в отмененном состоянии.

CreateLinkedTokenSource(CancellationToken)

Создает объект CancellationTokenSource , который будет находиться в состоянии отмены, когда предоставленный маркер находится в отмененном состоянии.

CreateLinkedTokenSource(CancellationToken[])

Создает объект CancellationTokenSource , который будет находиться в состоянии отмены, когда любой из исходных маркеров в указанном массиве находятся в отмененном состоянии.

CreateLinkedTokenSource(ReadOnlySpan<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 объектом.

См. также раздел