Middle
Como cancelar a execução de uma tarefa (task) em C#?
sobes.tech IA
Resposta da IA
Para cancelar a execução de uma tarefa em C#, utiliza-se o mecanismo CancellationToken e CancellationTokenSource.
- Cria-se um
CancellationTokenSource. - Obtém-se um
CancellationTokena partir doCancellationTokenSource. - O
CancellationTokené passado para um método que executa a tarefa. - Dentro do método em execução, verifica-se periodicamente a propriedade
IsCancellationRequesteddo token. - Se
IsCancellationRequestedfortrue, gera-se umaOperationCanceledExceptionou aplica-se outra lógica de finalização. - Para solicitar o cancelamento, chama-se o método
Cancel()no objetoCancellationTokenSource.
Exemplo de uso:
using System;
using System.Threading;
using System.Threading.Tasks;
// Criar uma fonte de tokens de cancelamento
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
// Criar uma tarefa
Task task = Task.Run(() =>
{
try
{
for (int i = 0; i < 100; i++)
{
// Verificar se foi solicitada cancelamento
if (token.IsCancellationRequested)
{
// Gerar uma exceção OperationCanceledException
token.ThrowIfCancellationRequested();
}
// Simulação de trabalho
Console.WriteLine($"Trabalhando... {i}");
Thread.Sleep(100);
}
}
catch (OperationCanceledException)
{
// Manipular exceção de cancelamento
Console.WriteLine("Tarefa cancelada.");
}
catch (Exception ex)
{
// Manipular outras exceções
Console.WriteLine($"Ocorreu um erro: {ex.Message}");
}
}, token); // Passar o token para a tarefa
// Esperar um tempo e solicitar cancelamento
Thread.Sleep(500);
Console.WriteLine("Solicitando cancelamento...");
cts.Cancel();
// Aguardar a tarefa terminar
try
{
task.Wait();
}
catch (AggregateException ae)
{
// Manipular exceções, incluindo OperationCanceledException
foreach (var e in ae.InnerExceptions)
{
if (e is OperationCanceledException)
{
Console.WriteLine("Tarefa cancelada (via Wait)." );
}
else
{
// Manipular outras exceções
Console.WriteLine($"Erro ao finalizar a tarefa: {e.Message}");
}
}
}
Console.WriteLine("Programa principal finalizado.");
Alternativas:
- Retornar um valor especial ou uma bandeira da tarefa.
- Verificar uma bandeira definida externamente, sem usar
CancellationToken.
No entanto, CancellationToken é a abordagem padrão e recomendada devido à sua integração com a Task Parallel Library (TPL), operações assíncronas e suporte para OperationCanceledException.