Sobes.tech
Middle

¿Cómo se puede cancelar la ejecución de una tarea (task) en C#?

sobes.tech AI

Respuesta de la IA

Para cancelar la ejecución de una tarea en C#, se utiliza el mecanismo CancellationToken y CancellationTokenSource.

  1. Se crea un CancellationTokenSource.
  2. Se obtiene un CancellationToken del CancellationTokenSource.
  3. El CancellationToken se pasa a un método que realiza la tarea.
  4. Dentro del método en ejecución, se verifica periódicamente la propiedad IsCancellationRequested del token.
  5. Si IsCancellationRequested es true, se genera una OperationCanceledException u otra lógica de finalización.
  6. Para solicitar la cancelación, se llama al método Cancel() en el objeto CancellationTokenSource.

Ejemplo de uso:

using System;
using System.Threading;
using System.Threading.Tasks;

// Crear un origen de tokens de cancelación
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

// Crear una tarea
Task task = Task.Run(() =>
{
    try
    {
        for (int i = 0; i < 100; i++)
        {
            // Verificar si se solicitó cancelar
            if (token.IsCancellationRequested)
            {
                // Generar una excepción OperationCanceledException
                token.ThrowIfCancellationRequested();
            }

            // Simulación de trabajo
            Console.WriteLine($"Trabajando... {i}");
            Thread.Sleep(100);
        }
    }
    catch (OperationCanceledException)
    {
        // Manejar la excepción de cancelación
        Console.WriteLine("Tarea cancelada.");
    }
    catch (Exception ex)
    {
        // Manejar otras excepciones
        Console.WriteLine($"Ocurrió un error: {ex.Message}");
    }
}, token); // Pasar el token a la tarea

// Esperar un tiempo y luego solicitar cancelación
Thread.Sleep(500);
Console.WriteLine("Solicitando cancelación...");
cts.Cancel();

// Esperar a que la tarea termine
try
{
    task.Wait();
}
catch (AggregateException ae)
{
    // Manejar excepciones, incluyendo OperationCanceledException
    foreach (var e in ae.InnerExceptions)
    {
        if (e is OperationCanceledException)
        {
            Console.WriteLine("Tarea cancelada (a través de Wait).");
        }
        else
        {
            // Manejar otras excepciones
            Console.WriteLine($"Error al finalizar la tarea: {e.Message}");
        }
    }
}

Console.WriteLine("La aplicación principal ha finalizado.");

Alternativas:

  • Retornar un valor especial o una bandera desde la tarea.
  • Verificar una bandera establecida externamente, sin usar CancellationToken.

Sin embargo, CancellationToken es el enfoque estándar y recomendado debido a su integración con la Task Parallel Library (TPL), operaciones asíncronas y soporte para OperationCanceledException.