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.
- Se crea un
CancellationTokenSource. - Se obtiene un
CancellationTokendelCancellationTokenSource. - El
CancellationTokense pasa a un método que realiza la tarea. - Dentro del método en ejecución, se verifica periódicamente la propiedad
IsCancellationRequesteddel token. - Si
IsCancellationRequestedestrue, se genera unaOperationCanceledExceptionu otra lógica de finalización. - Para solicitar la cancelación, se llama al método
Cancel()en el objetoCancellationTokenSource.
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.