envio de email em 2.plano

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

ola pessoal,
tenho uma rotina que envia varios emails, eu monto um array de emails e ela faz um loop e fica enviado...

Código: Selecionar todos


for x=1 to len(q_email)
     envia_email(q_email[x], rA_CORPOEMAIL)
     exibe_contagem(x)
next x

O problema é que enquanto envia os emails do array q_email com um contador de envio, o sistema fica parado ate que todos os emails sejam enviados.

Eu gostaria de fazer isso em segundo plano, exibindo o quadro de contagem em qualquer cantinho da tela, e liberando o usuário de fazer qualquer outra
coisa no sistema, ou seja, colocar o envio dos emails em segundo plano.

Trabalho do modo console ainda, harbour 3.1.

Se tiverem algum exemplo fácil para eu adaptar, ou alguma dica do caminho a seguir me ajudaria muito.

Desde ja Agradeço
ABEL
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

envio de email em 2.plano

Mensagem por asimoes »

Tipico para ser executado em uma Thread
►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)
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

asimoes, poderia postar algum exemplo, olhei no forum mas nao consegui usar nenhum exemplo.
precisava saber qual include tenho que compilar junto para usar thead

Desde ja agradeço,
ABEL
Avatar do usuário
dbsh
Usuário Nível 3
Usuário Nível 3
Mensagens: 128
Registrado em: 14 Jul 2004 14:19
Localização: ES

envio de email em 2.plano

Mensagem por dbsh »

Inclua a diretiva
-mt

EXEMPLO:
Não vai compilar, mas use como modelo se for util.

Código: Selecionar todos

METHOD AtivaMonitoramento() CLASS ProcessoPai
LOCAL nCount := 0

HB_MutexLock( ::ReadMutex )
HB_MutexLock( ::ErroMutex )

IF ::ReadMonitor
    IF !IsValidThRead( ::ReadThRead )
        ::ReadThRead := HB_ThReadStart( {|| AguardaDadosFRead( Self ) } )
    ENDIF
    IF !IsValidThRead( ::ReadThRead )
        ::ErroNumero += PROCESS_ERRO_START_THREAD
        Debug display "monitor erro ao carregar thread receber dados" + xStr(::ErroNumero), 11
        RETURN .F.
    ENDIF
ENDIF

IF ::ErroMonitor
    IF !IsValidThRead( ::ErroThRead )
        ::ErroThRead := HB_ThReadStart( {|| AguardaErroFRead( Self ) } )
    ENDIF
    IF !IsValidThRead( ::ErroThRead )
        ::ErroNumero += PROCESS_ERRO_START_THREAD
        Debug display "monitor erro ao carregar thread receber erro" + xStr(::ErroNumero), 11
        RETU .F.
    ENDIF
ENDIF

Debug display "monitor ThRead iniciado", 11

HB_MutexUnLock( ::ReadMutex )
HB_MutexUnLock( ::ErroMutex )

RETU .T.


010011110010000001110011011101010110001101100101011100110111001101101111001000001110100100100000011000110110111101101110011100110111010001110010011101011110110101100100011011110010000001100001001000000110111001101111011010010111010001100101
01001101011000010111001001100011011011110111001100100000010000010110111001110100011011110110111001101001011011110010000001000100011001010010000001000010011011110110111001101001
0101010001100101011011000011101000100000001010000011001000110111001010010011100100101101001110010011100000110100001100110010110100110101001100100011100100110000
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

envio de email em 2.plano

Mensagem por Itamar M. Lins Jr. »

Olá!
Não precisa exclusivamente de MT para rodar tarefas em segundo plano.

Código: Selecionar todos

#include "hbmemory.ch"

PROCEDURE Main()

   LOCAL nH1, nH2, nH3, nH4
   LOCAL n := 0
   LOCAL aSign := { "|", "/", "-", "\" }
   LOCAL nPrev := Seconds()

   CLS
   ? "   Time:        Memory used:                          Milliseconds elapsed"
   ?
   ? "Can you see it ??? :) Press any key or wait 30 seconds"
   ?
   ?
   @ 10, 2 SAY "Memory before TEST() call" + Str( Memory( HB_MEM_USED ) )
   TEST()
   @ 11, 2 SAY "Memory after TEST() and before collecting" + Str( Memory( HB_MEM_USED ) )
   hb_gcAll()
   @ 12, 2 SAY "Memory after collecting" + Str( Memory( HB_MEM_USED ) )
   nH1 := hb_idleAdd( {||                             hb_DispOutAt( 0,  1, Time() ) } )
   nH2 := hb_idleAdd( {|| TEST(),                     hb_DispOutAt( 0, 21, Memory( HB_MEM_USED ) ) } )
   nH3 := hb_idleAdd( {|| iif( n == 4, n := 1, n++ ), hb_DispOutAt( 0, 41, aSign[ n ] ) } )
   nH4 := hb_idleAdd( {||                             hb_DispOutAt( 0, 61, 1000 * ( Seconds() - nPrev ) ), nPrev := Seconds() } )

   ? ValType( nH1 ), nH1, ValType( nH2 ), nH2, ValType( nH3 ), nH3, ValType( nH4 ), nH4

   Inkey( 30 )
   IF ! Empty( nH3 )
      @ 14, 2 SAY "Delete task 3: " + hb_ValToStr( nH3 )
      hb_idleDel( nH3 )
   ENDIF
   IF ! Empty( nH2 )
      @ 15, 2 SAY "Delete task 2: " + hb_ValToStr( nH2 )
      hb_idleDel( nH2 )
   ENDIF
   IF ! Empty( nH1 )
      @ 16, 2 SAY "Delete task 1: " + hb_ValToStr( nH1 )
      hb_idleDel( nH1 )
   ENDIF
   IF ! Empty( nH4 )
      @ 17, 2 SAY "Delete task 4: " + hb_ValToStr( nH4 )
      hb_idleDel( nH4 )
   ENDIF

   @ 18, 2 SAY "Memory after idle states" + Str( Memory( HB_MEM_USED ) )
   hb_gcAll()
   @ 19, 2 SAY "Memory after collecting" + Str( Memory( HB_MEM_USED ) )

   RETURN

STATIC PROCEDURE TEST()

   LOCAL a, b, c
   LOCAL cb

   a := Array( 3 )
   b := Array( 3 )
   c := Array( 3 )
   a[ 1 ] := a
   a[ 2 ] := b
   a[ 3 ] := c
   b[ 1 ] := a
   b[ 2 ] := b
   b[ 3 ] := c
   c[ 1 ] := a
   c[ 2 ] := b
   c[ 3 ] := c

   cb := {| x | x := cb }
   Eval( cb )

   RETURN
HB_IDLEADD()
Adds the background task.
Syntax
HB_IDLEADD( <bAction> ) --> nHandle
Arguments
<bAction> is a codeblock that will be executed during idle states. There are no arguments passed to this codeblock during evaluation.
Returns
<nHandle> The handle (an integer value) that identifies the task. This handle can be used for deleting the task.

Description
HB_IDLEADD() adds a passed codeblock to the list of background tasks that will be evaluated during the idle states. There is no limit for the number of tasks.
Examples
nTask := hb_idleAdd( {|| SayTime() } )

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

envio de email em 2.plano

Mensagem por asimoes »

Tinha esquecido de HB_IDLEADD, também deve funcionar, só toma cuidado de deletar o idle após o término do envio de email
►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
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

envio de email em 2.plano

Mensagem por Itamar M. Lins Jr. »

Olá!
só toma cuidado de deletar o idle após o término do envio de email
IF ! Empty( nH1 )
@ 16, 2 SAY "Delete task 1: " + hb_ValToStr( nH1 )
hb_idleDel( nH1 )
ENDIF

Olhar no exemplo que postei e se possível executar para ver funcionando.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

oi pessoal, estava fazendo um teste de uma rotina em segundo plano e aparentemente no comando send() a tarefa em segundo plano para de funcionar e só retorna quando o send() termina sua execucao.

a minha ideia é que a tarefa em segundo plano fique algo na tela simulando um processamento para não parecer que travou mesmo que a pesquisa demora 10segs
por exemplo.

Desde ja agradeço !
ABEL

Código: Selecionar todos


// MEU FONTE
NTURN=0
NTURN1=0
rN_T=ATIVA_2PLANO()
//
CONSULTA_REQUISICAO()
//
DESATIVA_2PLANO(rN_T)



FUNCTION CONSULTA_REQUISICAO()    
  Local oOle, aRet, 
  //
  @ 5, 1 + 1 SAY "A"
    
    TRY
       oOle:=win_OleCreateObject("MSXML2.XMLHTTP")  
    Catch
       oOle:=CreateObject("Microsoft.XMLHTTP")
    End
    //
    @ 5, 1 + 1 SAY "B"
    oOle:Open( 'POST', "https://ws.apicep.com/cep.json?code=06233-030" , .f. )  // ESSE É UM EXEMPLO DE REQUISICAO Q ESTOU USANDO NO TESTE 
    //
    @ 5, 1 + 1 SAY "C"
    
    oOle:setRequestHeader("Content-Type", "application/json" )
    //
    @ 5, 1 + 1 SAY "D"   // aqui a funçao que esta rodando em segundo plano para até o send() ser executado
    //
    TRY 
       oOle:Send( )      
       
    CATCH
       //
       ALERT2('VERMELHO','Problemas na Consulta ...')  
       //
       RETURN ""
    End   
    //
    @ 5, 1 + 1 SAY "E"
    aRet:=oOle:Responsetext
    Do While oOle:readyState <> 4
       millisec(500)
    ENDDO
    //
    @ 5, 1 + 1 SAY "F"
    ALERT(aRet)
    //
    
RETURN ""  




PROCEDURE ATIVA_2PLANO()
X := hb_idleAdd( {|| Progress( @nTurn1, 30, 35 ) } )
RETURN X

PROCEDURE DESATIVA_2PLANO(X)
hb_idleDel( X )
RETURN 


PROCEDURE Progress( nProgress, nDrow, nDcol )

   LOCAL rA_CHAR, nRow := Row(), nCol := Col()

   
   @ nDrow-1, nDcol-1 SAY "     " COLOR 'W/G+'
   @ nDrow  , nDcol-1 SAY " [ ] " COLOR 'W/G+'
   @ nDrow+1, nDcol-1 SAY "     " COLOR 'W/G+'
   
   @ nDrow-1, nDcol+4 SAY "                                 " COLOR 'G/W*'
   @ nDrow  , nDcol+4 SAY " Aguarde, fazendo a consulta ... " COLOR 'G/W*'
   @ nDrow+1, nDcol+4 SAY "                                 " COLOR 'G/W*'
   
   DO CASE
      CASE nProgress = 0
          @ nDrow, nDcol + 1 SAY "-" COLOR 'W+/G+'
      CASE nProgress = 1
          @ nDrow, nDcol + 1 SAY "\" COLOR 'W+/G+'
      CASE nProgress = 2
          @ nDrow, nDcol + 1 SAY "|" COLOR 'W+/G+'
      CASE nProgress = 3
          @ nDrow, nDcol + 1 SAY "/" COLOR 'W+/G+'
   ENDCASE
   nProgress++

   IF nProgress == 4
      nProgress := 0
   ENDIF
RETURN


Avatar do usuário
carlaoonline
Usuário Nível 3
Usuário Nível 3
Mensagens: 190
Registrado em: 24 Ago 2014 22:38
Localização: Porto Alegre-RS

envio de email em 2.plano

Mensagem por carlaoonline »

Bom dia!


Quem sabe criar um segundo aplicativo que é chamado pelo principal apenas para essa função.....
Um segundo aplicativo pode ser compilado apenas com as bibliotecas que vai precisar pra ele ao inves de todos os que tem no principal, pode ser feito em MiniGui, HMG, C, etc...

Ex.:
HB_RUN ( "ENVIA.EXE" )
ou

RUN ENVIA.EXE



Ele pode rodar com uma tela bem menor que caiba apenas a mensagem, pode rodar minimizado ou até sem tela (em segundo plano apenas na memória)...
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

Ola,
seria uma ideia realmente, mas nao queria um outro EXE,
meu sistema é modo console, poderia ate ser uma janelinha windows de mensagem,
mas nao consegui fazer, uma mensagem em janela tipo windows com algo em movimento
demonstrando que esta sendo processado alguma tarefa.

att
ABEL
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

envio de email em 2.plano

Mensagem por Itamar M. Lins Jr. »

Olá!
Simples, coloque a rotina, msg aqui dentro:

Código: Selecionar todos

    Do While oOle:readyState <> 4 
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

envio de email em 2.plano

Mensagem por Itamar M. Lins Jr. »

Olá!
Cadê de fato a rotina que demora ? pq esse exemplo nem pisca, é muito rápido pegar CEP.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

oi Itamar,

não posso publicar aqui o http que chama essa API que demora um pouco para retornar, pq é particular desse cliente e ele não me autoriza.
coloquei a do cep como um exemplo apenas.

essa API faz o seguinte:
- ela abre um site, preenche dois campos, clica em um botao pesquisar, pega o resultado da pesqusisa, e devolve uma matriz que recebo no harbour e processo o resultado. Acho que essa api foi feita em phyton. Pelo harbour nao consegui desenvolver essa solucao por completo.

o ideal é que eu tivesse uma solucao direto pelo harbour sem a necessidade de chamar essa API

vou tentar colocar a msg do readystate

Obrigado por enquanto
Abel
Usuário Nível 3
Usuário Nível 3
Mensagens: 332
Registrado em: 14 Mar 2012 13:16
Localização: sao paulo / sp

envio de email em 2.plano

Mensagem por Abel »

ola pessoal,

segue o trecho em harbour que faz a requisicao

Código: Selecionar todos

    oOle:Open( 'POST', "http://....." , .f. )
    //
    oOle:SetRequestHeader('token', nToken )  
    oOle:setRequestHeader("Content-Type", "application/json; charset=UTF-8" )
    oOle:SetRequestHeader( "Connection",       "keep-alive" )
    rA_BODY='{ "cpf": "'+ALLTRIM(rA_CPF)+'"  , "data": "'+dtoc(rD_DTNASC)+'" }'
    //
    TRY
       oOle:Send( rA_BODY )     // é aqui que ocorre o travamento temporario as vezes e aparece na janela console "nao respondendo..."
                                            // e ate mesmo uma janelinha em 2.plano que fiz para de funcionar, pois o harbour esta esperando um retorno

       // oOle:WaitForResponse( 100000 )  // nao faz diferença por ou tirar isso
   CATCH
       ALERT2('VERMELHO','Problemas na Consulta ...')  
       RETURN "CANCELA CONSULTA"
    End   
    //
    aRet:=oOle:Responsetext
    Do While oOle:readyState <> 4     // itamar quando chega aqui eu ja tenho o retorno do SEND(), entao nao adiantou colocar msg aqui 
       millisec(500)
    ENDDO
    RETURN aRet

Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

envio de email em 2.plano

Mensagem por Itamar M. Lins Jr. »

Olá!
Parece que é falha do SITE que RECEBE e RESPONDE, e não do programa. Porquê nessa parte é o SO(win) que gerência. É a mesma coisa que mandar imprimir via windows e ficar demorando sem imprimir, não resta nada a fazer a não ser esperar mesmo.

Teria que monitorar na CHEGADA. Tipo: Sim recebi sua solicitação e Ok! Enviei a resposta solicitada!

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Responder