CancellationToken
ResumoUm
CancellationTokenpermite cancelar operações assíncronas de forma cooperativa — por exemplo, quando o cliente da API desiste da requisição. Propagá-lo evita trabalho desperdiçado.
1. Objetivos de Aprendizagem#
- Aceitar e propagar
CancellationToken. - Reagir ao cancelamento.
- Entender o cancelamento cooperativo.
2. Pré-requisitos#
- Task e async/await (tópico 11.1).
3. Conceito#
Cancelamento em .NET é cooperativo: o código precisa observar o token e parar quando ele for sinalizado. Uma CancellationTokenSource gera o token e dispara o cancelamento; os métodos assíncronos o recebem e o repassam adiante.
O porquê: numa Web API, se o cliente fecha a conexão, o ASP.NET Core sinaliza o token da requisição. Repassá-lo ao banco evita continuar uma consulta cujo resultado ninguém mais quer.
4. Mão na Massa#
4.1. Setup#
dotnet new console -n Catalog.Cancel
cd Catalog.Cancel
4.2. Implementação Passo a Passo#
- Aceitar e propagar o token:
async Task<string> BuscarAsync(CancellationToken ct)
{
await Task.Delay(2000, ct); // Delay observa o token
return "ok";
}
- Disparar o cancelamento (ex.: timeout de 1s):
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
try
{
var r = await BuscarAsync(cts.Token);
Console.WriteLine(r);
}
catch (OperationCanceledException)
{
Console.WriteLine("Operação cancelada por timeout.");
}
- Verificar manualmente em laços longos:
async Task ProcessarAsync(IEnumerable<int> itens, CancellationToken ct)
{
foreach (var item in itens)
{
ct.ThrowIfCancellationRequested(); // aborta se cancelado
await Task.Delay(100, ct);
}
}
4.3. Executando#
dotnet run
5. Exemplo Completo#
Um CancellationTokenSource com timeout de 1s cancela uma operação de 2s, e o catch (OperationCanceledException) trata o cancelamento graciosamente — o padrão para respeitar limites de tempo.
6. Boas Práticas e Armadilhas#
| Faça | Evite |
|---|---|
Aceitar CancellationToken em métodos assíncronos públicos | Ignorar o token recebido e não propagá-lo |
| Repassar o token para chamadas internas (EF Core, HttpClient) | Capturar OperationCanceledException e tratá-la como erro real |
Verificar ThrowIfCancellationRequested() em laços longos | Trabalho longo que nunca observa cancelamento |
Atençãocancelamento não é forçado — se o seu código não observar o token, a operação continua. Sempre propague-o até a operação de I/O de fato.
7. Segurança e Produção#
- Em controllers ASP.NET Core, adicione um parâmetro
CancellationTokenàs actions: o framework injeta o token da requisição automaticamente, evitando trabalho órfão quando o cliente desiste.
8. Exercícios#
- Fácil: cancele um
Task.Delaycom um token de timeout. - Médio: propague um token por dois níveis de métodos assíncronos.
- Desafio: implemente um laço que aborta em até 100ms após o cancelamento.
9. Resumo#
CancellationToken habilita cancelamento cooperativo: o código deve observar e propagar o token. Na API, o token da requisição evita trabalho desperdiçado quando o cliente desiste.
10. Próximos Passos#
A seguir, as armadilhas clássicas do assíncrono.
11. Referências#
- Microsoft Learn — Cancelamento em threads gerenciadas
- Microsoft Learn — CancellationToken
- Microsoft Learn — Cancelamento em ASP.NET Core