Fórum Duvida no uso de Threads (syncronize) #364329
26/09/2008
0
estou com um sério problema, tenho uma aplicação que alem de fazer N coisas, é também um client de email. Porém ao efetuar um cadastro ou fazer qualquer outra coisa no sistema fica lento enquanto emails estao sendo baixados ou enviados, no meu form principal eu tenho uma StatusBar que indica o recebimento do email, ou seja..
É perfeitamente possivel que o usuário esteja no form principal ou cadastrando um cliente e apareça na statusbar Recebendo mensagem 1 de 10 (13kb de 200kb) por exemplo..
Enfim, esse é meu cenario e meu problema se iniciou aí, para resolve-lo criei threads que chamam as procedures de envio e recebimento, porém evetualmente um erro ou outro ocorre. Procurei em vários topicos e em varios sites e vi que minhas rotinas para atualizacao na barra de status por exemplo deveriam ser realizadas utilizando o syncronize, mas estou com uma duvida cruel, como eu utilizo o syncronize na minha procedure de envio ou recebimento, se isso deve ocorrer no evento onreceive do meu objeto por exemplo?
Saint
Curtir tópico
+ 0Posts
29/09/2008
Saint
tudo o que eu quero é saber como trabalhar com as threads se parte do meu código está nos eventos dos objetos chamados pelas threads..
Gostei + 0
29/09/2008
Prgdelphi
Se estiverem, não adianta nada vc utilizar as threads, se elas estão chamando funções na thread principal, quando estas estiverem executando, o seu programa vai ter que aguardar do mesmo jeito.
Você deve criar todos esses componentes dentro da thread e manipular tudo la dentro. Ligar as funções com os eventos dos componentes, etc.
O máximo que você tera que fazer que podera impactar (muito pouco) a execução do seu programa é atualizar a StatusBar no form principal, para indicar o progresso. Neste caso sim, você terá que usar o synchronize.
Foi isso que entendi da sua dúvida, caso eu tenha entendido errado por favor me corrija.
Gostei + 0
30/09/2008
Saint
eu tenho um objeto POP que está no meu form principal, é instanciado lá.
mas na minha thread eu o utilizo pra dar o retrieve, ou seja..
no Execute da minha thread tem lá:
frmPrincipal.POP.retrieve(MeuObjetoMSG,1);
isso em si deixava meu sistema parado enquanto o pop dava o retrieve e após jogar na thread, a melhora foi extremamente visível..o sistema realmente não para.
porém a rotina que atualiza por exemplo a minha barra de status fica no evento OnReceive desse pop..
aí qual o problema? o problema é que eventualmente são gerados erros no meu sistema e esses erros não tem nenhum padrão, nem geram uma excessao no delphi, é simplesmente um erro que dá, não cai em nenhum except e quando o exe está rodando da um erro do windows, aí o usuário clica em não enviar o relatório do erro pra microsoft e o sistema continua executando. Pelo que vi, o erro em si deve ser por algum tipo de atualizacao visual no meu form principal, seila..algo deve tentar gravar em algum endereco de memória que pode estar em uso, enfim..deve ser algo da thread.
Entao eu acredito que pra corrigir isso, devo trabalhar da forma correta com a thread e atualizar minha barra de status a partir da thread diretamente, mas nao sei como fazer isso se a informação que eu preciso (quantos bytes vieram por exemplo) está no evento OnReceive lá do meu POP. Entendeu???
Gostei + 0
30/09/2008
Prgdelphi
Entendi sim o que vc ta fazendo... foi isso mesmo que eu imaginei...
o que ta gerando as exceptions é a sua thread acessando direto as funções do form principal (Thread principal).
O que vc deve fazer:
- retire o objeto POP do seu form principal e declare-o dentro do objeto da thread.
- do seu form principal, copie a função retrieve do pop e declare-a tb dentro do objeto da thread.
- no create da thread, crie o objeto pop e inicialize com todas as informações necessarias, inclusive faça o link do evento retrieve do pop com a função (pop.onretreave = thread.funcaoretreave, ou alguma coisa assim).
beleza... faça alguns testes de recebimento assim, vc vera que não ira gerar mais nenhuma exception.
Mais uma coisa, essas mensagens vc deve estar armazenando em alguma tabela, ou ainda arquivo, que tb é acessado pelo form principal. Não faça nenhuma chamada à componentes do formprincipal para gravar esses dados.
Se estiver usando uma tabela por exemplo ADO para gravar, crie tudo dentro da thread (ADOconnection e ADOTable) e faça as conexões e gravações por aí.
feito isso, você tera que atualizar a barra no seu form principal.
no form principal crie um procedimento que faz essa atualização, por exemplo procedure AtualizaBarra(valor : string); e dentro desta procedure coloque la statusbar1.panels[0].text := valor, ou qualquer outra coisa que queira...
voltando à thread, crie uma variavel global para armazenar o valor que vc vai mandar para a função do form principal.
crie um outro procedimento somente para chamar o procedimento do form principal. assim:
procedure AtualizaBarraNoFormPrincipal;
begin
FrmPrincipal.AtualizaBarra(VariavelGlobalDaThreadComOValor);
end;
No evento on receive do pop faça assim:
variavelglobal := inttostr(pop.bytesreceived);
Synchronize(AtualizaBarraNoFormPrincipal);
desculpe pela maneira como escrevi... mas estou sem o Delphi aqui e não lembro algumas propriedades de cabeça...
Vai dar um trabalhinho pra vc fazer essas alterações, mas pode ter certeza que vai dar certo...
Gostei + 0
30/09/2008
Saint
quando li seu outro post temi que tivesse que fazer isso pq realmente vai dar um trampo hehehe..so queria mesmo ter certeza pq nao queria perder um tempo implementando isso e depois continuar dando esses exceptions, mas pelo que entendi vou ter que fazer isso mesmo, mas beleza pq agora ja tenho praticamente certeza de que vai funcionar, era essa a informacao que eu queria..
eu imaginei que a thread pudesse eventualmente acessar algum objeto do form que fosse ´nao visual´ sem problemas, mas entao pelo que entendi ela precisa ser auto-suficiente, né?
tudo o que eu for utilizar nela, ela mesmo tem que ter..e ai o form ou qualquer coisa do mundo externo é que precisa ler algo dela caso necessario..mas nunca ela utilizar outra coisa, agora peguei o fio da meada hehehe..
valeu cara, brigadao..vou implementar isso e posto aqui o resultado, valeu mesmo!
abraco!
Gostei + 0
03/10/2008
Saint
valeu mesmo, ajudou pra caramba...
tirei todas as chamadas da thread e a deixei auto suficiente, fiz tudo dentro dela e fiz com que ela alimentasse as variaveis globais que depois sao lidas pelo resto do sistema e utilizadas..
valeu mesmo, abraco!
Gostei + 0
06/10/2008
Prgdelphi
É isso aí... threads é meio chato de mexer mas é só pegar o jeito.
Boa sorte no desenvolvimento...
abraço
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)