Fala ai Radizeiro e Radizeira, tudo bem com você?

Nossa série tem sido muito legal, e creio que vocês tem aproveitado bastante.

Poder pensar mais na experiência do usuário, na usabilidade do seu software tem se tornando mais atrativo para o seus clientes.

Chega de ficar com telas sem respostas, travando a cada interação com consultas, sejam elas web ou direta em uma tabela com um fluxo grande de dados.

E pensando sempre nisso venho trazendo essas séries para você, e claro, dentro do CLUBE DOS PROGRAMADORES EM DELPHI, existem conteúdos que irão auxiliar nos seus dia a dia.

O clube tem uma gama de conteúdos, e novos conteúdos mensalmente, para ajudar vocês que fazem parte, e se hoje você não está no CLUBE DOS PROGRAMADORES EM DELPHI, clique no link que encontra-se nessa página e saiba mais sobre o clube, e vem fazer parte do maior portal de conteúdo Delphi da atualidade.

Em posts anterior falei sobre o TCriticalSection e o Monitor, funções disponíveis dentro do Delphi e que nos ajuda bastante em nossas implementações.

E no post de hoje irei falar um pouco mais sobre Thread, e irei mostrar uma outra forma de fazer Thread.

Você que tem acompanhado a série sobre paralelismo, onde mostrei sobre as TTasks, iFuture, iTask, dentre outras formas legais de se trabalhar com paralelismo.

Mas tem uma forma que podemos fazer que é criar uma classe herdando da classe de Threads.

Quando fazemos isso, essa nossa classe, obrigatoriamente irá rodar dentro de uma Thread.

Mas você já deve estar pensando, como é que fazemos isso?

Você que me acompanha constantemente, sabe que eu gosto sempre de atrelar a teoria com a prática.

Dessa forma irei criar uma classe TProcesso herdando de TThread, você que conhece sobre a orientação a objetos já consegue compreender sobre esse conceito de herança.

Tudo que for executado nessa nossa classe, será executado em numa thread separada.

TProcesso = class(TThread)
    private
    public
        procedure Execute; override;
end;

A única obrigatoriedade que temos que ter nessa nossa classe é um método que denominamos de Execute com sobrescrita.

Dentro desse nosso exemplo, iremos atualizar um memo no formulário usando thread.

Então irei criar uma thread. e possuo a classe do meu form principal, sendo que quero que o meu memo seja atualizado usando a classe de Thread que acabei de criar.

E para isso tenho que programar dentro do método Execute da minha classe de Thread.

Só que primeiro irei criar alguns objetos dentro desta minha classe para trabalharmos melhor com a nossa classe.

TProcesso = class(TThread)
    private
        FMemo : TMemo;
        FAux : String;
    public
        constructor Create(aMemo : TMemo); reintroduce;
        procedure Execute; override;
        procedure Sincronizar;
end;
...
procedure TProcesso.Create(aMemo : TMemo);
begin
    inherited Create(True);
    FreeOnTerminate := True;
    FMemo := aMemo;
end;

procedure TProcesso.Execute;
var
    I : Integer;
begin
    inherited;
    for I := 0 to 1000 do
    begin
        FAux := 'Valor = ' + I.ToString;
        Self.Queue(Self.Sincronizar);
    end;
end;

procedure TProcesso.Sincronizar;
begin
    FMemo.Lines.Add(FAux);
end;

Observe que criei um método construtor usando injeção de dependência, onde ele recebe um Memo e reintroduz o construtor.

E logo em seguida eu criei um método para trabalhar a sincronização.

Dentro do método Create eu chamei o FreeOnTerminate para não precisar me preocupar em destruir, onde quando terminar ele irá limpar essa minha thread.

Observe que dentro do método Execute para que eu enviasse os valores para o memo utilizei o método Sincronizar.

E para rodar esse meu Sincronizar eu precisei colocar dentro de uma Thread.Queue, porque todas as vezes que for atualizar um objeto na tela, precisamos utilizar o Sincronyze ou um Queue.

Nessa caso eu usei o Queue, em posts anteriores já expliquei a diferença, onde sincronize já chega atualizando independente de quem está rodando, e o Queue joga na fila e aguarda a thread principal finalizar um processo para aí ela ser executada.

Por este motivo eu utilizei o Queue, para aguardar minha thread principal terminar para depois sim ele ser atualizada.

Muito legal não é?

Criei uma classe que está herdando de TThread, ou seja, o que executar nessa classe já irá rodar em uma Thread separada, não irá ocupar o MainThread.

Mas agora como iremos fazer com que essa nossa classe trabalhe para nós agora?

Vamos lá…

Em nosso formulário, dentro do evento click do botão iremos implementar o código abaixo.

procedure TForm1.Button1Click(Sender: TObject);
var
    Processo : TProcesso;
begin
    Processo := TProcesso.Create(Memo1);
    Processo.Start;
end;

Observe que no create da classe simplesmente passei o memo e logo em seguida chamei o start da Thread, e pronto, os registros serão visualizados dentro do memo conforme criamos

Enquanto nossa Thread vai registrando os dados dentro do memo a nossa aplicação não trava.

Essa é mais uma da forma que podemos trabalhar usando a Thread.

Viu como é muito legal trabalhar com Thread?

Conteúdos como esse você consegue encontrar no CLUBE DOS PROGRAMADORES EM DELPHI, conteúdos ricos para auxiliar vocês que trabalham com Delphi.

E caso você tenha interesse de conhecer mais sobre PPL acessa o nosso portal do CLUBE DE PROGRAMADORES EM DELPHI, onde você não só terá conteúdos relacionados aos generics, mas uma quantidade enorme de conteúdos que poderá lhe ajudar muito no seu dia a dia, é uma verdadeira NETFLIX para os programadores Delphi.

CLIQUE AQUI E SAIBA MAIS SOBRE O CLUBE DOS PROGRAMADORES DELPHI