.NET Framework Tarea: cancelar usando CancelToken


Ejemplo

var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;

var task = new Task((state) =>
    {
        int i = 1;
        var myCancellationToken = (CancellationToken)state;
        while(true)
        {
            Console.Write("{0} ", i++);
            Thread.Sleep(1000);
            myCancellationToken.ThrowIfCancellationRequested();
        }
    },
    cancellationToken: cancellationToken,
    state: cancellationToken);

Console.WriteLine("Counting to infinity. Press any key to cancel!");
task.Start();
Console.ReadKey();

cancellationTokenSource.Cancel();
try
{
    task.Wait();
}
catch(AggregateException ex)
{
    ex.Handle(inner => inner is OperationCanceledException);
}

Console.WriteLine($"{Environment.NewLine}You have cancelled! Task status is: {task.Status}");
//Canceled

Como alternativa a ThrowIfCancellationRequested , la solicitud de cancelación se puede detectar con IsCancellationRequested y se puede lanzar una OperationCanceledException manualmente:

//New task delegate
int i = 1;
var myCancellationToken = (CancellationToken)state;
while(!myCancellationToken.IsCancellationRequested)
{
    Console.Write("{0} ", i++);
    Thread.Sleep(1000);
}
Console.WriteLine($"{Environment.NewLine}Ouch, I have been cancelled!!");
throw new OperationCanceledException(myCancellationToken);

Observe cómo el token de cancelación se pasa al constructor de tareas en el parámetro cancellationToken . Esto es necesario para que la tarea pase al estado Canceled , no al estado Con Faulted , cuando se invoca ThrowIfCancellationRequested . Además, por el mismo motivo, el token de cancelación se proporciona explícitamente en el constructor de OperationCanceledException en el segundo caso.