Um token de cancelamento é um objeto que permite que a colaboração interrompa operações assíncronas de longa duração. Eles são usados para evitar que as operações consumam recursos indefinidamente, mesmo que eles não sejam mais necessários.
Para usar um token de cancelamento, primeiro você deve criar um objeto CancellationTokenSource. Este objeto fornece um token de cancelamento que você pode passar para a operação que deseja cancelar.
A operação que recebe o token de cancelamento pode então verificar periodicamente o status do token. Se o status for IsCancellationRequested, a operação deverá interromper seu trabalho e retornar.
A desmarcação é uma ferramenta importante para programação assíncrona. Eles podem ajudar a garantir que suas operações consumam recursos de forma eficiente e parem quando necessário.
Aqui estão alguns exemplos de como usar tokens de cancelamento:
- Se o usuário clicar no botão Cancelar, a operação de download do arquivo será interrompida.
- Se o limite de tempo for atingido, a operação de processamento de dados será interrompida.
- Se a conexão for perdida, as operações de comunicação com o servidor remoto serão interrompidas.
A desmarcação é uma parte importante da programação assíncrona. Eles fornecem uma maneira segura e eficiente de interromper operações assíncronas longas.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace CancellationTokenExample
{
class Program
{
static void Main(string[] args)
{
// Cria um token de cancelamento
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
// Cria uma task demorada
Task.Run(() =>
{
// Verifica o status do token de cancelamento periodicamente
while (!cancellationToken.IsCancellationRequested)
{
// Faz algo demorado
Thread.Sleep(1000);
}
// Se o token de cancelamento foi solicitado, sai da task
Console.WriteLine("Cancelado!");
});
// Cancela a task após 3 segundos
Thread.Sleep(3000);
cancellationTokenSource.Cancel();
// Aguarda a task terminar
Task.WaitAll();
Console.WriteLine("Pronto!");
}
}
}
Você deve estar se perguntando: Por que cancelar uma tarefa se ela ainda não foi concluída?
É importante cancelar uma tarefa mesmo que ela ainda não tenha sido concluída. Isso porque, caso a tarefa não seja cancelada, ela continuará consumindo recursos indefinidamente.
No exemplo anterior, a tarefa demorada era realizar algo demorado, como baixar um arquivo grande ou processar grandes quantidades de dados. Se uma tarefa não for cancelada, ela continuará consumindo CPU, memória e recursos de rede mesmo que não seja mais necessária.
Cancelar uma tarefa também pode ajudar a evitar que ela cause danos. Por exemplo, se uma tarefa estiver fazendo alterações em um banco de dados, cancelar a tarefa impedirá que as alterações sejam feitas por engano.
Em alguns casos, você pode saber se uma tarefa foi concluída com êxito antes de cancelá-la. Por exemplo, se uma tarefa estiver baixando um arquivo, você poderá verificar o tamanho do arquivo baixado para ver se ele foi concluído.
Contudo, em muitos casos é impossível saber se uma tarefa foi concluída com sucesso até que seja cancelada. Por exemplo, se a tarefa estiver processando uma grande quantidade de dados, não será possível verificar se o processamento foi concluído.
De modo geral, é melhor cancelar uma tarefa mesmo que ela ainda não tenha sido concluída.
Digamos que eu crie um método get que chame uma tarefa que dura 15 minutos. Você deseja cancelar a qualquer momento chamando um método get. Como será esse método get?
Para cancelar uma tarefa a qualquer momento, você pode passar um token de cancelamento para o método get. O método get pode então verificar periodicamente o status do token de cancelamento. O método get pode cancelar a tarefa se um token de cancelamento for solicitado.
Aqui está um exemplo de como cancelar uma tarefa a qualquer momento e chamá-la usando um botão:
// Cria um token de cancelamento
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
// Cria uma task demorada
Task.Run(() =>
{
// Verifica o status do token de cancelamento periodicamente
while (!cancellationToken.IsCancellationRequested)
{
// Faz algo demorado
Thread.Sleep(1000);
}
// Se o token de cancelamento foi solicitado, sai da task
Console.WriteLine("Cancelado!");
});
// Invoca o método get
Task.Run(() =>
{
// Passa o token de cancelamento para o método get
GetAsync(cancellationToken);
});
// Aguarda a task terminar
Task.WaitAll();
// Cancela a task
Button.Click += (sender, e) =>
{
cancellationTokenSource.Cancel();
};
// Método get que recebe o token de cancelamento
static async Task GetAsync(CancellationToken cancellationToken)
{
// Verifica o status do token de cancelamento periodicamente
while (!cancellationToken.IsCancellationRequested)
{
// Faz algo demorado
Thread.Sleep(1000);
}
// Se o token de cancelamento foi solicitado, sai da task
Console.WriteLine("Cancelado!");
}
Neste exemplo, criamos um token de cancelamento e passamos o token para o método get. O método get verifica periodicamente o status do token de cancelamento. Se um token de cancelamento for solicitado, o método get será encerrado.
Para cancelar uma tarefa, você chama o método Cancel() do token de cancelamento.
Aqui está um exemplo de como cancelar uma tarefa:
// Cancela a task
cancellationTokenSource.Cancel();
Ao executar este código, teremos a saída:
...
Cancelado!
Pronto!