Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 1184 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Boa tarde pessoal, tudo bem?

Estou precisando de algumas dicas para uso de threads para controles paralelos. Já estou usando deste método porém em alguns casos meu aplicativo simplesmente trava durante a finalização da thread. Estou criando as mesmas da seguinte forma:

Teste := TThread.Create;

Teste.FreeOnTerminate := True;

Teste.Start;

Sendo que criei um método Create fazendo overload onde eu seto as variáveis que preciso utilizar no meu aplicativo com os valores necessários e dentro do método Execute estou utilizando um while para enquanto eu não tiver terminado todos os meus procedimentos continuar ali. Até aí tudo bem porém quando a Thread é finalizada em alguns casos simplesmente o sistema para de responder e fica ali travado com o caption "(Não respondendo)", mesmo debugando isso ocorre mas sem nenhum retorno de erro. Tentei realizar a chamada sem o FreeOnTerminate e utilizando o Terminate dentro do próprio Execute mas mesmo assim isso ocorre. Alguém tem alguma dica de como eu posso estar solucionando isso? Lembrando que eu estou criando a classe do tipo Thread dentro de um formulário VCL normal. Eu até criei um projeto separado para testar se o mesmo também ocorria e uma forma de solucionar, mas neste não ocorre. Vou deixar uma imagem abaixo deste projeto que é a forma como estou chamando a Thread e a construção dela.

image.png.9e6294ac4a84765638cc4590a8de25d7.pngimage.png.ba30163a6a7a71e65696eea327a5bda8.pngimage.png.c1deb3b10172add8c0c348d191b22f7a.png

Editado por MaikonPanazzolo
Faltava explicar alguns detalhes
Link para o comentário
Compartilhar em outros sites

  • Consultores

Você não pode acessar variáveis fora do contexto da Thread sem o método Synchronize. Então:

Em primeiro lugar, você não pode acessar o Form1 no método TTeste.Create.

Em segundo lugar, você não pode acessar a variável Terminou dentro do Execute fora do Synnchronize().

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

@EMBarbosaIsso é somente um esboço de exemplo, no projeto de fato não estou utilizando variáveis, o código que de fato estou utilizando é o seguinte:

image.thumb.png.c1e44ebf47a2161dfe24f2554c0020ec.png

Por favor ignorem a variável teste, utilizei apenas para inserir um breakpoint para testar se estava travando antes ou depois, e o travamento é exatamente nela.

Link para o comentário
Compartilhar em outros sites

  • Consultores

Com esse novo cenário que você passou fica um pouco difícil de analisar sem mais informações.

Por exemplo, o que você quer dizer com "o travamento é exatamente nela"?

Você não verifica o Terminate no Execute da thread. Está ciente que isso está faltando?

Quantas vezes a thread é criada? Ela é liberada da memória?

Onde foi definido essa variável Lista e idProprio? O que faz o método Existe? E o método SetObjDesktop?

Por que tem um Try..Except em branco?

Como a thread sai do loop while True se o Socket estiver conectado?

A propósito onde são definidos esses sockets?

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

Bom dia @EMBarbosa, pra facilitar eu vou responder na ordem das perguntas.

1 - Então, com o travamento da tela eu quero dizer que o sistema trava e até mesmo a mensagem "Não respondendo" é apresentada no caption do form e com isso eu não consigo mais clicar em nada nem fazer nada, o sistema trava e fica ali parado.

2 - Eu havia tentado fazendo a verificação usando o Terminate, tanto dentro do while quanto no próprio while ( while not terminated do) e mesmo assim não funcionou, pra ser sincero tentei de várias formas já.

3 - Por ser um sistema de conexões, a Thread é criada diversas vezes, e na liberação da memória, sou leigo no assunto ainda, mas utilizei na criação da Thread o (FreeOnTerminate := True) e aparentemente não me retornou nenhum memory leak no fechamento da aplicação então acredito que quanto a isso não haja problemas.

4 - A variável Lista é nada mais que um TCollection definida nas variáveis globais do código, eu fiz isso porque assim eu posso chamar em qualquer lugar, na qual eu uso para armazenar os dados das conexões junto com os objetos das Threads para serem chamados de outros locais quando necessário, já a propriedade IdProprio foi definido dentro da criação da própria Thread. E os métodos Existe e SetObjDesktop são para verificar se aquele registro existe na Lista TColletion e para armazenar o objeto da Thread também na lista respectivamente.

5 - O Try except foi mais uma das tentativas para evitar o travamento mas sem sucesso também.

6 - A thread não deve sair do while enquanto estiver conectada, isso porque existe uma relação entre as conexões, apenas quando uma das duas desconectarem que ambas as Threads vão parar.

7 - Os sockets são definidos dentro da própria Thread e são usados dois, uma para a própria conexão e um que recebe a conexão do computador conectado, por isso o "SocketTarget".

O objetivo do sistema seria para duas máquinas se conectarem e uma poder receber a captura da tela da outra, como um acesso remoto mesmo. Gostaria de se possível, umas dicas de como lidar com essas Threads como inicializa-las e como finaliza-las e já peço desculpas caso eu esteja equivocado em alguma colocação.

Vou deixar mais duas prints com toda a Thread e sua chamada abaixo.

Obrigado desde já.

image.thumb.png.7d849b2117f424cff6b3b83315be7d0b.png

image.thumb.png.d739967ff89cea7099f45a0fba83d70d.png

Link para o comentário
Compartilhar em outros sites

  • Consultores

Bom dia.

   Os próximos códigos que você colar, por favor, cole em modo texto. Isso facilita. Tem uma opção pra colar código no editor do post...

   Voltando...

1 hora atrás, MaikonPanazzolo disse:

1 - Então, com o travamento da tela eu quero dizer que o sistema trava e até mesmo a mensagem "Não respondendo" é apresentada no caption do form e com isso eu não consigo mais clicar em nada nem fazer nada, o sistema trava e fica ali parado.

Na verdade eu não perguntei sobre travamento da tela, eu me referi ao comentário que você fez anteriormente sobre a variável teste:

15 horas atrás, MaikonPanazzolo disse:

Por favor ignorem a variável teste, utilizei apenas para inserir um breakpoint para testar se estava travando antes ou depois, e o travamento é exatamente nela.

Como assim o travamento é na variável?

1 hora atrás, MaikonPanazzolo disse:

2 - Eu havia tentado fazendo a verificação usando o Terminate, tanto dentro do while quanto no próprio while ( while not terminated do) e mesmo assim não funcionou, pra ser sincero tentei de várias formas já.

Você precisa ter essa verificação no execute, especialmente quando faz um loop "While True".

Se a aplicação estiver sendo terminada, quem vai avisar a thread que ela pode parar de trabalhar?

Caso isso não aconteça ela vai continuar executando, passando a impressão que a aplicação está travada.

1 hora atrás, MaikonPanazzolo disse:

3 - Por ser um sistema de conexões, a Thread é criada diversas vezes, e na liberação da memória, sou leigo no assunto ainda, mas utilizei na criação da Thread o (FreeOnTerminate := True) e aparentemente não me retornou nenhum memory leak no fechamento da aplicação então acredito que quanto a isso não haja problemas.

Bom, se a aplicação está travada, ela não terminou. Se ela não terminou, não tem como verificar se houve memory leak...

Então não podemos afirmar nada, mas cuidado com isso...

1 hora atrás, MaikonPanazzolo disse:

4 - A variável Lista é nada mais que um TCollection definida nas variáveis globais do código, eu fiz isso porque assim eu posso chamar em qualquer lugar, na qual eu uso para armazenar os dados das conexões junto com os objetos das Threads para serem chamados de outros locais quando necessário, já a propriedade IdProprio foi definido dentro da criação da própria Thread. E os métodos Existe e SetObjDesktop são para verificar se aquele registro existe na Lista TColletion e para armazenar o objeto da Thread também na lista respectivamente.

Eu não posso dizer que compreendi bem a sua arquitetura aqui... mas você não deve acessar valores globais dentro do método Execute da thread. Se vai acessar qualquer valor fora da thread precisa no mínimo do método Synchronize (para acessar a thread principal) e em outros casos, Semáforos ou Mutex...

1 hora atrás, MaikonPanazzolo disse:

5 - O Try except foi mais uma das tentativas para evitar o travamento mas sem sucesso também

Não faça isso. Em threads, você precisa fazer um tratamento especial pra exceptions... Dá uma olhada no Google.

1 hora atrás, MaikonPanazzolo disse:

6 - A thread não deve sair do while enquanto estiver conectada, isso porque existe uma relação entre as conexões, apenas quando uma das duas desconectarem que ambas as Threads vão parar.

E se a aplicação estiver sendo terminada, como fica? E onde está o tratamento de sincronização entre as duas threads?

1 hora atrás, MaikonPanazzolo disse:

7 - Os sockets são definidos dentro da própria Thread e são usados dois, uma para a própria conexão e um que recebe a conexão do computador conectado, por isso o "SocketTarget".

Não é isso o que o código da chamada está mostrando. Você está passando um objeto já criado para o método Create da Thread... Então ele não faz parte da Thread.

É importante entender que a VCL não é inerentemente "thread safe". Então você precisa codificar para evitar locks e race conditions.

2 horas atrás, MaikonPanazzolo disse:

O objetivo do sistema seria para duas máquinas se conectarem e uma poder receber a captura da tela da outra, como um acesso remoto mesmo.

Nesse caso, acho melhor você procurar alguma coisa já pronta, ou pelo menos parcialmente pronta. Use o VNC por exemplo.

Desenvolver um acesso remoto não é tão fácil quanto parece...

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

Entendi, vou estar verificando essas situações, e continuar estudando formas para melhorar e corrigir esse problema, quanto ao VNC não cheguei a me basear nele, como exemplo usei o AllaKore que inclusive já foi postado aqui mesmo, mas fiz diversas mudanças para se aplicar ao meu uso. Referente ao tratamento das exceções busquei e não encontrei outra forma a não ser o try..except.

Link para o comentário
Compartilhar em outros sites

  • Consultores
1 hora atrás, MaikonPanazzolo disse:

Referente ao tratamento das exceções busquei e não encontrei outra forma a não ser o try..except.

https://stackoverflow.com/questions/3627743/delphi-thread-exception-mechanism

  • Curtir 1

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

  • 1 ano depois...
  • Consultores
14 horas atrás, Emm4P00le disse:

Por que fazer uma chamada sem FreeOnTerminate?

O FreeOnTerminate pode ser setado para false quando você deseja controlar manualmente a vida útil da thread.

Veja mais na documentação.
http://docwiki.embarcadero.com/Libraries/en/System.Classes.TThread.FreeOnTerminate

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Link para o comentário
Compartilhar em outros sites

Olá, Maikon. Tudo certo? Sou autodidata nesse ramo de códigos e programação, e estou com algumas dúvidas para entender esses pontos que você elencou. Começando por uma que talvez seja a mais simples de todas. Por que você diz que a thread não deve sair do while quando está conectada? Não entendo muito bem o porquê desse condicionamento. Eu faço uns códigos para o mystudybay e achei que essa condição não era seguida lá, com a thread fora do estado while ao me conectar. Pode me explicar melhor, por favor? Valeu, abraços.

Editado por EMBarbosa
Link parecido com SPAM removido.
Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 1184 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...