Cancelamento de TTasks em Delphi: Implementação e Exemplo Prático

Cancelamento de TTasks em Delphi
Cancelamento de Tarefas.

Introdução

Nesse post iremos abordar sobre o cancelamento de TTasks em Delphi. A importância do cancelamento, como executar e exemplo prático.

A programação assíncrona é essencial para manter a responsividade de aplicações modernas. Em Delphi, a classe TTask é amplamente utilizada para executar operações em segundo plano. No entanto, há casos em que precisamos cancelar essas operações de forma graciosa. Neste artigo, exploraremos como implementar o cancelamento de uma TTask e apresentaremos um exemplo prático para demonstrar o processo.

Quando devo utilizar o Cancelamento de TTask em Delphi

O cancelamento de TTask em Delphi deve ser utilizado em cenários onde é necessário interromper uma operação assíncrona antes de sua conclusão natural. Aqui estão algumas situações em que o cancelamento de uma tarefa (TTask) é recomendado:

  1. Operações Longas ou Pesadas:
    • Quando uma tarefa executa operações que podem demorar muito tempo, como processamento de grandes conjuntos de dados, downloads de arquivos, ou comunicação com servidores remotos, é importante oferecer ao usuário a possibilidade de cancelar essa operação para evitar frustrações e melhorar a experiência do usuário.
  2. Interatividade do Usuário:
    • Em aplicações onde o usuário pode decidir que não quer mais continuar uma operação que está em andamento. Por exemplo, se o usuário iniciou um relatório ou uma busca, mas decide que não quer mais esperar pelo resultado, ele deve ter a opção de cancelar a tarefa.
  3. Recursos Limitados:
    • Quando a tarefa está consumindo muitos recursos do sistema (CPU, memória, I/O), e o cancelamento é necessário para liberar esses recursos para outras operações mais prioritárias.
  4. Respostas a Eventos Externos:
    • Quando sua aplicação precisa responder rapidamente a eventos externos ou mudanças no estado da aplicação. Por exemplo, se a conexão com um servidor remoto é perdida, você pode querer cancelar todas as tarefas relacionadas a essa conexão.
  5. Melhor Gestão de Fluxo de Trabalho:
    • Quando múltiplas tarefas estão sendo executadas e algumas delas precisam ser interrompidas com base em resultados intermediários ou novas entradas do usuário. Isso ajuda a manter o fluxo de trabalho eficiente e responsivo.

Como Implementar o Cancelamento de uma TTask

Implementar o cancelamento de uma TTask envolve alguns passos fundamentais:

  1. Sinalização do Cancelamento: Precisamos de uma maneira de sinalizar que a tarefa deve ser cancelada.
  2. Verificação Periódica do Cancelamento: A tarefa deve periodicamente verificar se o cancelamento foi solicitado.
  3. Encerramento Gracioso: Quando o cancelamento é detectado, a tarefa deve encerrar suas operações de forma segura.

Sinalização do Cancelamento

Para sinalizar o cancelamento, podemos usar uma variável compartilhada, um objeto de sincronização como TEvent ou até mesmo o método Cancel da Task que seta a propriedade status para cancelado. No nosso exemplo, iremos utilizar o método Cancel que atualizará o Status para cancelado e será verificado periodicamente dentro da tarefa.

Verificação Periódica do Cancelamento

Dentro da tarefa, precisamos adicionar pontos de verificação para verificar se o cancelamento foi solicitado. Isso pode ser feito em locais estratégicos, especialmente em loops e operações demoradas.

Encerramento Gracioso

Quando o cancelamento é detectado, a tarefa deve liberar todos os recursos alocados e encerrar sua execução de forma ordenada.

Exemplo Prático de Cancelamento de uma TTask

Vamos implementar um exemplo prático que demonstra o cancelamento de uma TTask. Neste exemplo, criamos uma aplicação simples que executa uma tarefa em segundo plano e permite ao usuário cancelar a tarefa a qualquer momento.

Passo 1: Configurando o Projeto

  1. Abra o Delphi e crie um novo projeto VCL.
  2. Adicione dois botões (TButton) e um rótulo (TLabel) e um controlador de tempo (TTimer) ao formulário principal.
  3. Na seção uses do formulário principal, adicione System.Threading.

Passo 2: Implementando o Código

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, System.Threading;

type
  TForm1 = class(TForm)
    StartButton: TButton;
    CancelButton: TButton;
    StatusLabel: TLabel;
    procedure CancelButtonClick(Sender: TObject);
    procedure StartButtonClick(Sender: TObject);
  private
    { Private declarations }
    Task: ITask;
    procedure UpdateStatus(const Msg: string);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.StartButtonClick(Sender: TObject);
begin
  UpdateStatus('Tarefa iniciada...');

  Task := TTask.Run(
    procedure
    var
      I: Integer;
    begin
      for I := 1 to 100 do
      begin

        //verifica se o status da task está cancelado e cancela a execução
        if TTask.CurrentTask.Status = TTaskStatus.Canceled then
        begin

          TThread.Synchronize(nil,
            procedure
            begin
              UpdateStatus('Tarefa cancelada!');
            end);
          Exit;
        end;

        Sleep(50); // Simula uma operação demorada

        TThread.Synchronize(nil,
          procedure
          begin
            UpdateStatus('Progresso: ' + I.ToString + '%');
          end);
      end;

      TThread.Synchronize(nil,
        procedure
        begin
          UpdateStatus('Tarefa concluída!');
        end);
    end);
end;

procedure TForm1.CancelButtonClick(Sender: TObject);
begin
  if Assigned(Task) then //Verifica se a task está atribuída
    Task.Cancel; //Cancela a Task
end;

procedure TForm1.UpdateStatus(const Msg: string);
begin
  StatusLabel.Caption := Msg;
end;

end.

Explicação do Código

Componentes da Interface

  • StartButton: Inicia a tarefa em segundo plano.
  • CancelButton: Sinaliza o cancelamento da tarefa.
  • StatusLabel: Exibe o status da tarefa.

Lógica do Cancelamento

  1. StartButtonClick: Inicia a tarefa. A tarefa é executada em um loop de 1 a 100, simulando uma operação demorada com Sleep(50). Em cada iteração, a tarefa verifica se a tarefa está com status de cancelado. Se estiver cancelado, a tarefa sai do loop e atualiza o rótulo para “Tarefa cancelada!”. Caso contrário, atualiza o progresso.
  2. CancelButtonClick: Utiliza o método Cancel sinalizando o cancelamento da tarefa.
  3. UpdateStatus: Atualiza o texto de StatusLabel na interface gráfica.

Veja a ilustração abaixo:

Cancelamento de TTasks em Delphi
Ilustração do projeto.

Código fonte do exemplo

Você pode fazer o download do exemplo do projeto através do repositório do github:

https://github.com/Gisele-de-Melo/Cancelamento_TTask

Conclusão

O cancelamento de TTasks em Delphi é uma prática essencial para criar aplicações responsivas e robustas. Ao implementar o cancelamento, é importante:

  • Garantir que a tarefa verifique periodicamente o estado de cancelamento.
  • Usar TThread.Synchronize para atualizar a interface gráfica de forma segura.
  • Liberar todos os recursos de forma ordenada ao encerrar a tarefa.

Este exemplo prático fornece uma base sólida para implementar o cancelamento de TTasks em suas aplicações Delphi. Com essas técnicas, você pode melhorar a experiência do usuário e a estabilidade do seu software, garantindo que operações longas possam ser interrompidas de maneira segura e eficiente.

Posts Relacionados

Livros + e-books

Delphi para Android e iOS

codedelphi.com
codedelphi.com

Delphi Start

codedelphi.com

Programando em Delphi XE

Aprenda programar Delphi

Banco de Dados RAD Delphi

Delphi Programming Projects

Deixe um comentário