Clipper On Line • Ver Tópico - envio de email em 2.plano

envio de email em 2.plano

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

Moderador: Moderadores

 

envio de email em 2.plano

Mensagempor Abel » 25 Out 2020 19:52

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


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
Abel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor asimoes » 25 Out 2020 22:20

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)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

envio de email em 2.plano

Mensagempor Abel » 26 Out 2020 02:28

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
Abel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor dbsh » 26 Out 2020 09:00

Inclua a diretiva
-mt

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

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 de usuário

dbsh
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 115
Data de registro: 14 Jul 2004 14:19
Cidade/Estado: ES
Curtiu: 2 vezes
Mens.Curtidas: 15 vezes

envio de email em 2.plano

Mensagempor Itamar M. Lins Jr. » 26 Out 2020 09:12

Olá!
Não precisa exclusivamente de MT para rodar tarefas em segundo plano.
#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.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6944
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 311 vezes
Mens.Curtidas: 505 vezes

envio de email em 2.plano

Mensagempor asimoes » 26 Out 2020 09:35

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 de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

envio de email em 2.plano

Mensagempor Itamar M. Lins Jr. » 26 Out 2020 09:49

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.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6944
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 311 vezes
Mens.Curtidas: 505 vezes

envio de email em 2.plano

Mensagempor Abel » 14 Mar 2022 12:17

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


// 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

Abel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor carlaoonline » 17 Mar 2022 17:19

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)...
Avatar de usuário

carlaoonline
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 190
Data de registro: 24 Ago 2014 22:38
Cidade/Estado: Porto Alegre-RS
Curtiu: 73 vezes
Mens.Curtidas: 22 vezes

envio de email em 2.plano

Mensagempor Abel » 19 Mar 2022 12:46

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
Abel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor Itamar M. Lins Jr. » 19 Mar 2022 14:31

Olá!
Simples, coloque a rotina, msg aqui dentro:
    Do While oOle:readyState <> 4 


Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6944
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 311 vezes
Mens.Curtidas: 505 vezes

envio de email em 2.plano

Mensagempor Itamar M. Lins Jr. » 19 Mar 2022 14:35

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

Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6944
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 311 vezes
Mens.Curtidas: 505 vezes

envio de email em 2.plano

Mensagempor Abel » 30 Mar 2022 10:42

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: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor Abel » 30 Mar 2022 11:02

ola pessoal,

segue o trecho em harbour que faz a requisicao

    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

Abel
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 313
Data de registro: 14 Mar 2012 13:16
Cidade/Estado: sao paulo / sp
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

envio de email em 2.plano

Mensagempor Itamar M. Lins Jr. » 30 Mar 2022 11:12

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.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6944
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 311 vezes
Mens.Curtidas: 505 vezes

Próximo



Retornar para Harbour

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 3 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro