quinta-feira, 22 de janeiro de 2009

Threads - Conceito e exemplo em Delphi

Nesse post falarei a respeito de Threads no Delphi.
Threads são processos e segundo o dicionário, o verbo processar no termo computacional significa "tratar dados em computador a fim de obter informação sistematizada" ou "interpretar e executar instruções".
Toda vez que executamos um projeto no Delphi, o projeto aberto é uma thread na qual é o processo principal do seu sistema. Você pode estar pensando: "Mas para que eu preciso aprender sobre Threads?". Você já notou que toda vez que um trecho de código é executado no delphi, você só consegue mexer no seu sistema depois que tudo é executado. Não notou? Então faça o seguinte exemplo:

Crie um projeto VCL forms e arraste um button no seu formulário.
No Onclick de um botao, coloque o código abaixo, rode o programa e depois clique nele.
var
I: Integer;
begin
for I:=1 to 10000 do
begin

end;
end;

Notou que após que você clica no botao e enquanto o laço de repetição não foi finalizado, não é possível nem mover o seu formulário ou executar qualquer outra tarefa em seu aplicativo?
Isso acontece devido ao processo que esta rodando mas ainda não foi finalizado.
Mas e agora? Se eu quiser executar outra tarefa no meu aplicativo enquanto o laço de repetição ainda esta em loop?. É aqui que entra Threads de sistema!
Outro exemplo de Thread é o componente Timer do Delphi que enquanto você esta rodando seu aplicativo, você consegue fazer com que o timer atualize a hora em um label a cada segundo sem interferir nas outras execuções.


CRIANDO UMA CLASSE E TENDO COMO HERANÇA A CLASSE TTHREAD

Criaremos uma classe chamada TMinhaThread que extenderá a classe TThread que esta na unit Classes:

type
TMinhaThread = class(TThread)
private
procedure Execute; override;
end;

Na nossa classe criada, criamos uma procedure chamada Execute que deverá ser modificada(override/virtual) toda vez que herdamos a classe Tthread. Somos forçados a fazer isso pois a classe TThread possui o método Execute que é abstrato e segundo o conceito de Orienteção a objetos, toda classe que herda uma classe que possui métodos abstratos, deve implementar todos os métodos abstratos da mesma. Eu sei que você deve estar pensando: "E toda classe que possui métodos abstratos, deve ser abstrata.", mas orientação a objetos não é o foco do Post.

Pressione CTRL+SHIFT+C para o delphi criar a estrutura no método Execute.

procedure TMinhaThread.Execute;
var
I: Integer;
begin

try
for I:=0 to 10000 do
begin
Sleep(20);
end;
Except

end;
end;

Com a procedure já implementada, arraste outro button para o formulário e adicione o seguinte trecho de código:

var
//Cria a variavel minhaThread do tipo TMinhaThread
minhaThread: TMinhaThread;
begin
//Criação do objeto
minhaThread := TMinhaThread.Create(False);
minhaThread.FreeOnTerminate := true;
end;

O método create recebe um valor booleano que significa:
True - A Thread é iniciada porém ela é pausada ou seja, não executa o método Execute (imagine o componente Timer com a opção Enabled = false).
False - O método Execute é executado assim que a Thread é iniciada.

O método FreeOnTerminate, verifica se a Thread precisa ser liberada da memória assim que ela for finalizada. Com isso não precisamos dar um FreeAndNil.
Valor True para liberar da memória e False para permanecer armazenada.


Execute o botão e note que apesar do seu aplicativo estar em loop, você consegue movê-lo e até mesmo executar outras tarefas.

Outro exemplo onde podemos utilizar Threads é no download ou upload de múltiplos arquivos, pois com thread conseguimos fazer a transferência de vários arquivos ao mesmo tempo sem ser preciso esperarmos o término de cada um.


Todas as explicações que eu posto aqui no blog são de tarefas que pratico no dia-a-dia, mas caso algum leitor ache interessante eu postar algo de um determinado assunto, basta comentar em algum post ou me enviar um e-mail.

Blz pessoal?
See ya guys....

9 comentários:

Maikel Scheid disse...

Opa... muito legal o blog, parabéns!
To acompanhando... abraço.. t+

Anônimo disse...

Você conhece algum componente em delphi semelhante ao TTimer, porém em vez de milesegundos, o Intervalo ser em microsegundos?
se sim, me envie um e-mail. aliados_mdk@hotmail.com.br

Professor Wellington Telles disse...

Se fechar o programa antes de acabar a Thread vai dar erro e por isso no evento OnClose do form eu adicionei:

minhaThread.Suspend;

E a variável eu declarei:

var
Form1: TForm1;
minhaThread: TMinhaThread;


Se tiver uma sugestão melhor me avise.

http://professorwellingtontelles.blogspot.com/

Anônimo disse...

muito legal esse try...except em branco, ótima dica pra principiantes fazerem m.... depois

Tester disse...

"Outro exemplo de Thread é o componente Timer do Delphi que enquanto você esta rodando seu aplicativo, você consegue fazer com que o timer atualize a hora em um label a cada segundo sem interferir nas outras execuções."

Isto não é verdade, o compilador executará o comando do Timer quando acionado, interrompendo o processo que estava em andamento e seguir apos termino da execução do Timer, se o código do Timer entrar em loop o sistema irá travar.

Fabricio Luiz disse...

Parceiro, estava lendo sua postagem e achei muito interessante! Desconhecia o assunto.
Mas lendo aqui, pensei o seguinte:
Então eu poderia usar uma thread para meu sistema dar avisos como do tipo: "existem clientes esperando por atendimento a x tempo" ?

tipo uma funçao para verificar se existem clientes na fila de espera a muito tempo e por ai vai... a cada determinado tempo

agradeceria muito se me enviasse um exemplo no email fld25@live.com

Nilton Oliveira disse...

Maurício, preciso de uma ajuda sobre esta parte de Thread. Gostaria de um contato em pvt.

Diego disse...

man como eu faço pra te da um abraço , era isso que eu estava precisando, ninguem explicou tao bem como se funciona uma thread na net que nem voce ! parabéns.

Willian disse...

Parabéns! Ótima postagem.