Rotina em Segundo Plano

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Avatar do usuário
nilton579
Usuário Nível 1
Usuário Nível 1
Mensagens: 31
Registrado em: 05 Fev 2008 20:23
Localização: MANAUS
Contato:

Rotina em Segundo Plano

Mensagem 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?
Clenilton Alencar
Minigui Extended 18.06 -> 19.04
BRMake 2.05
Borland C++
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Rotina em Segundo Plano

Mensagem por fladimir »

Não poderia ser uma Thread em segundo plano?
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
nilton579
Usuário Nível 1
Usuário Nível 1
Mensagens: 31
Registrado em: 05 Fev 2008 20:23
Localização: MANAUS
Contato:

Rotina em Segundo Plano

Mensagem por nilton579 »

Não conheço Threads
Clenilton Alencar
Minigui Extended 18.06 -> 19.04
BRMake 2.05
Borland C++
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Rotina em Segundo Plano

Mensagem 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.
Inacio de Carvalho Neto
Avatar do usuário
nilton579
Usuário Nível 1
Usuário Nível 1
Mensagens: 31
Registrado em: 05 Fev 2008 20:23
Localização: MANAUS
Contato:

Rotina em Segundo Plano

Mensagem 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".
Clenilton Alencar
Minigui Extended 18.06 -> 19.04
BRMake 2.05
Borland C++
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Rotina em Segundo Plano

Mensagem 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.
Inacio de Carvalho Neto
Avatar do usuário
nilton579
Usuário Nível 1
Usuário Nível 1
Mensagens: 31
Registrado em: 05 Fev 2008 20:23
Localização: MANAUS
Contato:

Rotina em Segundo Plano

Mensagem 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.
Clenilton Alencar
Minigui Extended 18.06 -> 19.04
BRMake 2.05
Borland C++
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Rotina em Segundo Plano

Mensagem 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.
Inacio de Carvalho Neto
cjp
Usuário Nível 6
Usuário Nível 6
Mensagens: 1563
Registrado em: 19 Nov 2010 22:29
Localização: paraná
Contato:

Rotina em Segundo Plano

Mensagem 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.
Inacio de Carvalho Neto
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Rotina em Segundo Plano

Mensagem 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.
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
nilton579
Usuário Nível 1
Usuário Nível 1
Mensagens: 31
Registrado em: 05 Fev 2008 20:23
Localização: MANAUS
Contato:

Rotina em Segundo Plano

Mensagem por nilton579 »

Pablo, a ideia de progressbar é boa. Dá ideia de avanço do processo. Vou explorar sua sugestão.
Muito obrigado!
Clenilton Alencar
Minigui Extended 18.06 -> 19.04
BRMake 2.05
Borland C++
alxsts
Colaborador
Colaborador
Mensagens: 3109
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Rotina em Segundo Plano

Mensagem 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...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20416
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Rotina em Segundo Plano

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Rotina em Segundo Plano

Mensagem por asimoes »

Mestre Quintas,

Qual é a diferença entre HB_THREAD_MEMVARS_COPY e HB_THREAD_INHERIT_MEMVARS ?
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20416
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

Rotina em Segundo Plano

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (Linux/Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder