Nenhum componente visual deve ser manipulado dentro de uma thread secundária. 
Acredito que isto seja devido a própria estrutura do Windows e não 
especificamente do Delphi.
Outros componentes, que não tenham absolutamente nada relacionado com tela, 
podem perfeitamente ser utilizados dentro de thread.
Porém, por experiência própria sei que conexões com banco de dados e 
componentes da Indy devem ser criados uma instância pra cada thread, e no caso 
da Indy 2 ou mais threads jamais devem utilizar a mesma porta.

Quanto a exemplos, infelizmente não posso fornecer, pois os locais onde utilizo 
threads estão muito integrados com o sistema. Mas qualquer dúvida poste aí que 
se eu souber eu te ajudo.

Eli Flávio Bortolotte


--- Em delphi-br@yahoogrupos.com.br, André Geraldo dos Santos 
<andresanto...@...> escreveu
>
> Eli,
> Boa noite.
> 
>     Obrigado pelas dicas, mas teria como você postar um exemplo da
> implementação da sua thread?
>     E com relação ao tratamento de exceções como você costuma trabalhar?
> 
>     Quando fala-se em VCL, de quais componentes você está se referindo?
>     Estou perguntando isso porque um processamento de banco de dados seja
> com IBX,DBX entre outros caracteriza o uso da VCL
>     implicitamente. Ou será que estamos falando de compartilhamento de
> objetos entre a thread pai e filha?
> 
>     Com relação ao Synchronize você pode observar que está até comentado,
> porque usando ele é a mesma coisa de estar rodando sem a thread.
> 
>     Aguardo retorno.
> 
> 2009/8/26 eliflaviob <elifla...@...>
> 
> >
> >
> > André, usar thread é algo complexo e precisa ser muito bem analisado. Nunca
> > execute nada da VCL dentro de uma thread, absolutamente nada. Você precisa
> > tomar muito cuidado com o banco de dados também, precisa ser uma conexão com
> > o banco exclusiva para a thread, não pode compartilhar a da thread principal
> > senão dá pau.
> > Outra coisa, percebi que você roda o único método FExecMethod1 dentro do
> > Synchronize, deste jeito não está adiantando nada ter uma thread, pois ela
> > está rodando na thread principal.
> >
> > Este código é de um relatório? O que você poderia colocar na thread é a
> > consulta ao banco de dados, pois a montagem do relatório precisa ser na
> > thread principal (synchronize) pois senão dá pau.
> >
> > Percebi também que você dispara a thread e fica em looping esperando ela
> > finalizar. Eu faço de outra maneira que considero melhor: passo um método de
> > referência para a thread para que ela chame após o término. Desta forma eu
> > disparo a thread e libero totalmente o sistema para o usuário. Quando ela
> > termina ela chama o evento dentro do Synchronize, onde eu finalizo a
> > operação, destruo a thread e exibo as informações para o usuário. Um outro
> > detalhe muito importante é que a thread só pode ser destruída pela thread
> > principal, se você destruí-la após terminar o Execute, dentro dela mesmo,
> > ela não sairá de memória até que o programa seja finalizado.
> >
> > Eli
> >
> > --- Em delphi-br@yahoogrupos.com.br <delphi-br%40yahoogrupos.com.br>,
> > André Geraldo dos Santos <andresantos78@> escreveu
> >
> > >
> > > Pessoal,
> > > Bom dia.
> > >
> > > Estou tendo um problema ao executar um processamento dentro de uma
> > > thread, meu caso é o seguinte.
> > > Montei uma classe que herda de Thread conforme descrito abaixo.
> > >
> > > Está thread foi criada com o objetivo de separar os processamentos
> > > pesados da aplicação principal
> > > evitando travamento, congelamento(Tela branca) entre outros problemas na
> > > aplicação durante a excução de determinados processos.
> > >
> > > Pesquisando na internet achei algumas coisas a respeito mas não ajudou
> > > muito, algumas pessoas dizem que neste caso o
> > > metodo deve ser sincrozinado(safe mode) porque qualquer operação que
> > > envolva a vcl é considerada como unsafe,
> > > realmente testei e funcionou porém a tela congela do mesmo jeito.
> > >
> > > Meu windows é XP SP3, e notei que no WinXP SP2 isso não acontecia até
> > > porque tenho outras implementações onde utilizo
> > > está mesma técnica de thread e funciona perfeitamente.
> > >
> > > O mais estranho é que o processo executa sem problemas quando uso thread
> > > unsafe, mas quando vou fechar a aplicação principal ocorre o erro.
> > Algumas
> > > pessoas dizem que o problema pode estar ligado a forma como crio e
> > destruo o
> > > form mas já testeis de diversas formas e o erro persiste.
> > >
> > > Aproveitando eu gostaria de saber como vocês tratam exceções geradas
> > > dentro de uma thread, devolvendo o controle para aplicação principal.
> > >
> > >
> > >
> > > *** Escopo da Classe ***
> > >
> > > type
> > > TProcExec1 = procedure () of object;
> > >
> > > TSistemaThread = Class (TThread)
> > > private
> > > protected
> > > procedure Execute; override;
> > > procedure processaFExecMethod1;
> > > public
> > > FExecMethod1 : TProcExec1;
> > > constructor Create(_Method : TProcExec1); overload;
> > > procedure sisOnTerminate;
> > > function ThreadTerminated : Boolean;
> > > end;
> > >
> > > implementation
> > >
> > > constructor TPharmacyThread.Create(_Method: TProcExec1);
> > > begin
> > > inherited Create(false);
> > > FExecMethod1 := _Method;
> > > FreeOnTerminate := False;
> > > boThreadTerminate := True;
> > >
> > > end;
> > >
> > > procedure TPharmacyThread.Execute;
> > > begin
> > > try
> > > try
> > > Self.Priority := tpNormal;
> > > if Assigned(FExecMethod1) then begin
> > > //Synchronize(processaFExecMethod1);
> > > processaFExecMethod1;
> > > end;
> > > except
> > > {Tratamento}
> > > end;
> > > finally
> > > phOnTerminate;
> > > end;
> > > end;
> > >
> > > procedure TPharmacyThread.phOnTerminate;
> > > begin
> > > FExecMethod1 := nil;
> > > inherited Terminate;
> > > boThreadTerminate := false;
> > > end;
> > >
> > > function TPharmacyThread.ThreadTerminated: Boolean;
> > > begin
> > > result := self.Terminated;
> > > end;
> > >
> > > procedure TPharmacyThread.processaFExecMethod1;
> > > begin
> > > FExecMethod1;
> > > end;
> > >
> > > *** Exemplo de utilização ***
> > >
> > > procedure TFRMRel_Vendas.btnOKClick(Sender: TObject);
> > > var
> > > Thread : TSistemaThread;
> > > begin
> > > criaFormAguarde;
> > > FRMRel_Vendas.Enabled := False;
> > > if rdgTipoRel.ItemIndex = 0 then
> > > Thread :=
> > > TPharmacyThread.Create(preparaRelatorioVendaSelacaoPorItem)
> > > else Thread :=
> > > TPharmacyThread.Create(preparaRelatorioVendaSelecaoPorSaida);
> > > try
> > > try
> > > Thread.Resume;
> > > while (Thread.boThreadTerminate) do begin
> > > Application.ProcessMessages;
> > > end;
> > > except
> > > destroiFormAguarde;
> > > FRMRel_Vendas.Enabled := True;
> > > FreeAndNil(Thread);
> > > end;
> > > finally
> > > destroiFormAguarde;
> > > FRMRel_Vendas.Enabled := True;
> > > FreeAndNil(Thread);
> > > end;
> > > FRMRel_Vendas.Enabled := True;
> > > Application.ProcessMessages;
> > > end;
> > >
> > > Atenciosamente,
> > >
> > > ----------------------------------------------------------
> > > André Geraldo dos Santos
> > >
> > > Analista de Sistemas/Desenvolvedor
> > > Belo Horizonte / Minas Gerais
> > > E-mail : andresantos78@
> > > ----------------------------------------------------------
> > >
> > >
> > > [As partes desta mensagem que não continham texto foram removidas]
> > >
> >
> >  
> >
> 
> 
> 
> -- 
> 
> Atenciosamente,
> 
> ------------------------------------------------------------
>                André Geraldo dos Santos
> 
>  Analista de Sistemas/Desenvolvedor
>  Belo Horizonte / Minas Gerais
>  E-mail   : andresanto...@...
> ------------------------------------------------------------
> 
> 
> [As partes desta mensagem que não continham texto foram removidas]
>


Responder a