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....

5 comentários:

Maikel Scheid disse...

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

mardoqueu 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.