Alfonso CV Posted July 7, 2018 at 08:42 PM Report #611253 Posted July 7, 2018 at 08:42 PM Olá pessoal. Uso Lazarus 1.8.4 Tenho uma aplicação que lê dados remotos, imagem e documentos gravados numa base de dados, o assunto é que quando são grandes e demoram um pouco a gente acha que o sistema está bloqueado, já coloquei barra de progresso e GIF dinâmico mas quando começa a fazer download estes controles param e o programa não responde. Também, se são varias imagens pequenas de 200 KB por exemplo depois de iniciar até não concluir o processo de download a aplicação não responde. Já usei DELAY e SLEEP para refrescar o Form entre download e nada, a aplicação entra num estado de Stand-by e até não terminar não responde. Alguma dica??? Cumprimentos,
nunopicado Posted July 8, 2018 at 08:30 AM Report #611254 Posted July 8, 2018 at 08:30 AM O problema é que estás a fazer o download na thread principal, onde também corre o UI do programa. Em termos simplistas, numa mesma thread, o CPU do computador pode correr apenas uma instrução de cada vez... Tu estás a tentar fazer as instruções do download e as instruções da actualização do UI em simultâneo, pelo que uma delas acaba por ficar para trás. Por causa disto, quando há processos demorados, estes devem ser corridos numa segunda thread, deixando a principal encarregue de actualizar o UI. Assim já funcionará correctamente. "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Alfonso CV Posted July 9, 2018 at 11:21 AM Author Report #611260 Posted July 9, 2018 at 11:21 AM Olá Nuno. Consegui resolver o problema colocando no código o seguinte: Application.ProcessMessages; Cumprimentos.
Popular Post nunopicado Posted July 9, 2018 at 02:22 PM Popular Post Report #611265 Posted July 9, 2018 at 02:22 PM (edited) O Application.ProcessMessages é largamente usado para 'desenrascar' esse problema, mas o seu uso não é sem custos... Este método serve para 'avisar' o programa para processar as mensagens (duh! 😄) que estão na queue do Windows, independentemente de quais são e do risco associado à execução de mensagens fora de ordem. Antes de mais, uma explicação simplista do que são 'mensagens': O GUI do Windows funciona porque os seus elementos enviam mensagens uns aos outros com indicação do que querem fazer. Por exemplo, quando clicas num botão, é enviada uma mensagem para o componente encarregue de alterar o aspecto visual do botão (que o faz parecer 'pressionado' visualmente) que por sua vez manda uma mensagem à form para se redesenhar para que o novo aspecto seja mostrado, há uma mensagem a dar iniciação do trabalho do botão, etc. Ao fazer ProcessMessages, estás a forçar a main thread do programa a executar tudo o que estiver na fila, e isto tem, de entre outras, as seguintes consequências: Estás a parar temporariamente a execução da tarefa principal, obrigando-a a demorar mais tempo Estás a mandar executar mensagens a meio da tarefa, sem saber quais as mensagens que lá estão nem os problemas que a sua execução forçada pode causar. No caso, a tua ideia faz com que ele pare a leitura dos dados, actualize o UI ao processar as mensagens de actualização que estão pendentes, e volta a ler, e voltar a parar, e por aí fora até completar a leitura. Como à primeira vista, isto funciona, muita gente o faz. O que muitos desconhecem é que, ao fazer isto, podem estar com uma simples linha a introduzir bugs no programa, bugs esses que são de detecção extremamente difícil pois existem pela execução de mensagens fora da ordem correcta. O caso é tal que podes correr um programa e dar tudo bem, voltas a correr sem alterar nada e os bugs manifestam-se, voltas a correr e está tudo bem, voltas a correr e aparecem bugs completamente diferentes dos primeiros. Ou seja, o pesadelo de qualquer programador. Por outro lado, dependendo das mensagens pendentes, o resultado pode nem ser o esperado, e não resolve sequer o problema inicial. Podes agora 'resolver' assim, e noutro programa em que te depares com um problema semelhante, resolves usar o mesmo, mas nesse outro programa não funcionar, por um qualquer motivo. Isto retira-te a previsibilidade das soluções, o que te obrigará a perder tempo à procura da solução de cada vez que te surgir o problema. E se o utilizador for dado a clicar à toa enquanto espera, como há tantos por aí, o resultado é muitas vezes o crash do programa, porque independentemente de lhe mandarmos processar as mensagens, a thread continua a ser só uma, e nem sempre com capacidade de fazer tudo o que lhe pedem. Nota: Não estou com isto a dizer que nunca se deve usar o ProcessMessages, ou que no teu caso não resolva o problema sem introduzir outros. Tudo depende do código circundante ao ProcessMessages. E mesmo quando os bugs aparecem, podem ser coisas tão banais quanto uma barra de progresso que anda para a frente e depois volta atrás, para depois voltar pra frente, não afectando nada de especial senão o aspecto visual. Mas há casos bem mais graves, o que me leva a recomendar que quem não saiba exactamente o que está a acontecer, ignore o 'remendo' que é o ProcessMessages, em favor de uma solução mais previsível, como o uso de multi-threading. Nota 2: Multi-threading não é, no entanto, um mar de rosas. É preciso perder algum tempo para sequer começar a ter ideia do ninho de ratos que aquilo é. No entanto, a partir do momento que saibas usar e implementares com as devidas protecções, é mais previsível e consistente do que correr mensagens desconhecidas a meio de uma tarefa. Edited July 9, 2018 at 02:51 PM by nunopicado 3 Report "A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!" > Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.
Alfonso CV Posted July 10, 2018 at 09:04 PM Author Report #611282 Posted July 10, 2018 at 09:04 PM Olá Nuno. Como já tenha dito, de momento resolvi mas acho que vamos a ter em conta teu comentário pois se facilita a execução do programa e contribui a ser um bocadinho mais rápido alem das possíveis consequências quando se produz alguns erro vale a pesa dar uma olhada neste tema. Cumprimentos.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now