Página 1 de 4
Rotina em Segundo Plano
Enviado: 24 Mar 2017 11:28
por nilton579
Bom-dia!
Estou com uma situação ainda sem solução.
Tenho que realizar uma consulta numa base postgre que envolve vários registros. Como o número de registros é grande, durante a abertura da query a aplicação fica com a tela branca. O usuário acaba tentando clicar na aplicação e aparece a mensagem que a aplicação não está respondendo e, por fim, o usuário acaba fechando a aplicação achando que a mesma travou.
Gostaria de poder dar um DO EVENTS (ou outro método) que faça um refresh na tela a fim de que não dê a impressão de que o aplicativo está travado.
Infelizmente, o DO EVENTS só iria funcionar se estivesse num loop (do while / fornext).
Daí pensei em colocar uma procedure que ficasse rodando em segundo plano e dando um DO EVENTS a cada 10 segundos. Fiz com um TIMER mas não funcionou, porque ele fica congelado enquanto o processo da query não finaliza.
Vi algo como HB_Idle... ou HB_BackGround... mas não consegui implementar.
Alguém teria um código para estudo do caso?
Rotina em Segundo Plano
Enviado: 24 Mar 2017 12:55
por fladimir
Não poderia ser uma Thread em segundo plano?
Rotina em Segundo Plano
Enviado: 24 Mar 2017 13:15
por nilton579
Não conheço Threads
Rotina em Segundo Plano
Enviado: 24 Mar 2017 14:27
por cjp
Eu não uso Minigui, só modo console mesmo, mas o que eu faço pra isso é fazer uma aplicação à parte apenas para rodar coisas que não precisam da intervenção do usuário. Então, essa aplicação à parte fica rodando sozinha, o usuário não mexe, e daí não atrapalha a aplicação principal.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 15:00
por nilton579
Inácio, no meu caso o usuário precisa intervir pois precisará definir, por exemplo, uma data.
Depois que clicar em "Visualizar" e o processo começar, é que vem a situação: tela branca, usuário clica na área, "programa parou de responder".
Rotina em Segundo Plano
Enviado: 24 Mar 2017 15:03
por cjp
Mas então por que vc não cria, na tela principal, os dados, para rodar depois na tela secundária?
Por exemplo, pegue todos os dados, salve num arquivo (dbf, txt etc), e programe o secundário para rodar com esses dados.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 15:16
por nilton579
Mas os dados só são obtidos depois que o usuário define o intervalo de datas.
É assim: o aplicativo possui apenas uma tela onde ficam 4 controles: os campos para o usuário informar a data inicial e a data final, o botão para iniciar a consulta e um grid onde os registros serão exibidos conforme o intervalo de datas informado.
O sistema abre uma consulta numa tabela postgresql, filtrando os registros de acordo com a data de cadatro (obedecendo o intervalo de datas informado pelo usuário). Depois que ele conclui a consulta, varre o objeto e vai inserindo os registros na grid.
O problema é que, antes que o processo de consulta seja finalizado, a tela fica branca, dando a impressão de que o programa travou. É isso que quero contornar.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 15:43
por cjp
Não sei se te entendi bem, mas o que te sugeri foi que vc separe a parte que requer a intervenção do usuário da parte que não requer, fazendo a primeira na tela principal e a segunda na tela secundária.
Então, na tela principal, vc dá as opções para o usuário, ele faz as escolhas que tem que fazer para efetivar a consulta.
Daí vc salva essa escolha do usuário num arquivo e libera a tela principal para o usuário fazer qualquer outra coisa.
Daí entra a tela secundária que irá efetivar as alterações na base de dados de acordo com as escolhas pré-salvas.
Me entende?
Não sei se isso se aplica ao que vc precisa, pois ainda não entendi bem o que vc precisa, mas foi assim que eu resolvi o meu caso.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 15:44
por cjp
Outra opção seria vc deixar na tela avisos claros para o usuário não mexer no programa enquanto esse aviso estivesse sendo exibido.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 17:13
por Pablo César
Oi Milton. Apenas uma idéia.
Assim como fladimir falou, você poderia usar threads.
Atualmente e tão apenas recentemente (graças ao Dr. Claudio e Mr.Quintas pela persistência tbm), posso te afirmar que em HMG funciona, mas terá que atualizar o seu HMg 3.4.3 com o PATCH numero 2 (antes faz o 1, é claro). Tem exemplos no SAMPLES na subpasta MultiThread e tem uma recente que não é multi é apenas um thread.
http://www.hmgforum.com/viewtopic.php?p=50180#p50180
Na sua função onde cria a thread e processa os dados, você poderia atualizar um ProgressBar para dar sensação de movimento pro usuário.
Rotina em Segundo Plano
Enviado: 24 Mar 2017 17:27
por nilton579
Pablo, a ideia de progressbar é boa. Dá ideia de avanço do processo. Vou explorar sua sugestão.
Muito obrigado!
Rotina em Segundo Plano
Enviado: 24 Mar 2017 18:40
por alxsts
Olá!
Pelo que percebi nos posts, o processo é síncrono, ou seja, para que o processamento local continue, é necessário que a rotina em execução no banco de dados seja completada. Assim, não seria possível colocar um progressbar que refletisse o andamento real da operação no banco de dados. Também não daria para usar thread pois, da mesma forma, o processamento local teria que aguardar a finalização da thread...
O Pablo recomenda atualização da HMG mas o colega usa Minigui.
Sou mais pela ideia de colocar um box na tela pedindo ao usuário que aguarde.
Outra providência importante é analisar a query do banco e ver se é possível melhorar a performance, através de chaves primárias e índices...
Rotina em Segundo Plano
Enviado: 28 Mar 2017 09:06
por JoséQuintas
Compare a thread com um RUN ( "programa.exe" )
Seu aplicativo apenas vai fazer a pausa, enquanto a thread busca as informações.
Essa busca não ficaria visível na tela, então seria só pra não ter tela congelada, que no final vai ficar parada do mesmo jeito, mas o usuário vai poder clicar.
É que tem o detalhe do Windows poder considerar que a janela travou e querer fechar tudo.
Mas entra uma questão que requer muita atenção:
- Talvez possa ser uma janela invisível - sem janela não vai dar pro usuário mexer com o mouse, e impede esse travamento de janela
- Caso use multithread, tem que lembrar que a LIB precisa aceitar isso, principalmente pra poder apresentar mensagens de erro ou qualquer outra coisa
Dependendo do caso, poderia fazer um select count(*) primeiro, pra ter a quantidade total e avisar ao usuário.
Se a demora for pela quantidade de registros, e não por pesquisa demorada, pode valer a pena.
Convém lembrar deste post:
https://pctoledo.org/forum/viewto ... 45&t=18111
Rotina em Segundo Plano
Enviado: 28 Mar 2017 10:39
por asimoes
Mestre Quintas,
Qual é a diferença entre HB_THREAD_MEMVARS_COPY e HB_THREAD_INHERIT_MEMVARS ?
Rotina em Segundo Plano
Enviado: 28 Mar 2017 10:53
por JoséQuintas
Código: Selecionar todos
// Inherit copy of public
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PUBLIC, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
// ? "Inherit copy of privates."
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_PRIVATE, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
// ? "Inherit copy of publics and privates."
// hb_threadJoin( hb_threadStart( HB_BITOR( HB_THREAD_INHERIT_MEMVARS, HB_THREAD_MEMVARS_COPY ), @thFunc() ) )
Pelo que parece, um não tem nada a ver com o outro, não se trata de opções diferentes
Todos tem HB_THREAD_MEMVARS_COPY