Aqui vai alguns conceitos sobre a classe TThread, que compartilho contigo:
Resume ou Start:
O método Resume coloca a thread para funcionar, ou seja, executa o método Execute.
No Delphi 2010 Resume está deprecated, sendo usado o Start.
Suspend:
O método Suspend suspende a thread do ponto em que estiver.
Terminate:
O método Terminate seta a proriedade Terminaded para True, apenas isso... Dentro do Execute é que está o segredo...
WaitFor:
A função WaitFor é que efetivamente aguarda o término da thread. Mas cuidado! Para que funcione corretamente temos que tomar três cuidados, do contrário você esperará eternamente...
Terminated
No Execute, tome cuidado com a variável Terminated, sempre vericando em pontos estratégicos. O exemplo básico é o que segue abaixo... Friso: EXEMPLO BÁSICO:
procedure TMinhaThread.Execute; begin try while not (Self.Terminated) do begin Sleep(10); Application.ProcessMessages; {...} {...} //Ponto estratégico para verificação... if (Self.Terminated) then Abort; {...} {...} end; except on E: Exception do begin {...} end; end; end;
Evento OnTerminate
Você deve setar o evento OnTerminate, senão o WaitFor não retorna...
Cuidado com a thread suspensa!
Se a thread estiver suspensa, o WaitFor também não retorna. O código mais correto para terminar uma thread é o que segue abaixo:
procedure TForm1.Button3Click(Sender: TObject); var cRet : Cardinal; begin //Manda Terminar.... Self.FThread.Terminate; //Verifica se a thread não esta suspensa... if not (Self.FThread.Suspended) then begin //Aguarda o término da Thread cRet := Self.FThread.WaitFor; Log(Format('Retornou: [%d]',[cRet])); end else begin Log('Esta suspenso'); end; //Livra a instância... Self.FThread.Free; Self.FThread := nil; end;
ReturnValue
A função WaitFor retorna um valor Integer... e da onde vem este valor? Da propriedade ReturnValue, que poderá ser setada no Execute.
Abort
Abort, como sabido, gera uma exceção do tipo EAbort, e na minha opnião é a maneira mais apropriada de terminar a execução de um Execute. Veja no trecho de código acima.
Syncronize
Syncronize executa um método pela thread principal. Na minha opnião só é válido em aplicativos GUI (com interface gráfica). Fora desta situação, dê preferência para TCriticalSection.
Por ora é isso. Existem outros aspectos mas acho esse os mais importantes.
Aproveito para compartilhar um PDF que a anos me ajuda a enfrentar as treads:
http://docs.google.com/fileview?id=0B2-0qFgCBKnjNmJhZjg2NDktYjIyOS00ODA0LTk0MjgtZGFhZDJiYzhkODJm&hl=pt_BR
Uma outra leitura interessante sobre o assunto:
http://balaiotecnologico.blogspot.com/search?q=thread