.NET Framework Compito: cancellare usando CancellationToken


Esempio

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

In alternativa a ThrowIfCancellationRequested , la richiesta di annullamento può essere rilevata con IsCancellationRequested e una OperationCanceledException può essere generata 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);

Nota come il token di cancellazione viene passato al costruttore di task nel parametro cancellationToken . Ciò è necessario in modo che le transizioni compito alle Canceled stato, non alla Faulted stato, quando ThrowIfCancellationRequested viene richiamato. Inoltre, per lo stesso motivo, il token di cancellazione viene esplicitamente fornito nel costruttore di OperationCanceledException nel secondo caso.