Para ver el artículo en inglés, active la casilla Inglés. También puede ver el texto en inglés en una ventana emergente si pasa el puntero del mouse por el texto.
Traducción
Inglés

Task Cancellation

.NET Framework (current version)
 

Las clases System.Threading.Tasks.Task y System.Threading.Tasks.Task<TResult> admiten la cancelación a través del uso de tokens de cancelación en .NET Framework. Para obtener más información, véase Novedades en el SDK Visual Studio 2015. En las clases Task, la cancelación implica la cooperación entre el delegado de usuario, que representa una operación que se puede cancelar y el código que solicitó la cancelación.  Una cancelación correcta significa que el código que la solicita llama al método CancellationTokenSource.Cancel y que el delegado de usuario finaliza la operación a tiempo. Puede finalizar la operación a través de una de estas opciones:

  • Devolver simplemente un valor del delegado. En muchos escenarios esto es suficiente; sin embargo, una instancia de tarea cancelada de esta manera cambia al estado TaskStatus.RanToCompletion, no al estado TaskStatus.Canceled.

  • Producir una excepción OperationCanceledException y pasarle el token en el que se solicitó la cancelación. En este caso, se prefiere usar el método ThrowIfCancellationRequested. Una tarea cancelada de esta manera cambia al estado Canceled, que sirve al código que realiza la llamada para comprobar que la tarea respondió a su solicitud de cancelación.

En el siguiente ejemplo se muestra el modelo básico para la opción de cancelación de tareas que produce la excepción. Observe que el token se pasa al delegado de usuario y a la propia instancia de la tarea.

using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            while (moreToDo)
            {
                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }

            }
        }, tokenSource2.Token); // Pass same token to StartNew.

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
                Console.WriteLine(e.Message + " " + v.Message);
        }
        finally
        {
            tokenSource2.Dispose();
        }

        Console.ReadKey();
    }
}

Para obtener un ejemplo más completo, vea How to: Cancel a Task and Its Children.

Cuando una instancia de tarea observa una excepción OperationCanceledException iniciada desde el código de usuario, compara el token de la excepción con su token asociado (el que se pasó a la API que creó la tarea). Si son iguales y la propiedad IsCancellationRequested del token devuelve true, la tarea lo interpreta como una confirmación de cancelación y pasa al estado Canceled. Si no se usa un método Wait o WaitAll para esperar a la tarea, esta simplemente establece su estado en Canceled.

Si espera en un elemento Task que cambia al estado “Canceled”, se crea y se inicia una excepción System.Threading.Tasks.TaskCanceledException (encapsulada en la excepción AggregateException). Observe que esta excepción indica la cancelación correcta en lugar de una situación de error. Por consiguiente, la propiedad Exception del elemento Task devuelve null.

Si la propiedad IsCancellationRequested del token devuelve False o si el token de la excepción no coincide con el token de la tarea, OperationCanceledException se trata como una excepción normal, por lo que la tarea cambia al estado Faulted. Observe también que la presencia de otras excepciones también hará que la tarea pase al estado Faulted. Puede obtener el estado de la tarea completada en la propiedad Status.

Es posible que una tarea continúe procesando algunos elementos una vez solicitada la cancelación.

Mostrar: