Page 1 of 2

StartThread NO es estable usando FiveWin

Posted: Wed Oct 03, 2018 2:00 pm
by albeiroval
Buen dia,

Necesito ejecutar un proceso en un hilo (thread), no me sirve trabajarlo con TIMER.
La aplicacion al cabo de un tiempo se bloquea y un genera un GPF, estoy usando Harbour y Borland 7.0,
las librerias MT hbvmmt.lib de harbour y cw32mt.lib de Borland, este es el codigo :

Code: Select all

nSeconds := 30
bThread  := {|oMsgItem, nSeconds| DownloadReportes( oMsgItem, nSeconds )}

ACTIVATE WINDOW oWnd; 
        MAXIMIZED;
        VALID lExit;
        ON INIT ( OpenServerMySQL( oWnd ),;
                  Crear_AutoReporteZ(),;
                  MsgWinMainBar(),;
                  pThread := StartThread( bThread, oMsgItem, nSeconds ) )

StopThread( pThread )
WaitForThreads()

Return Nil


Function DownloadReportes( oMsgItem, nSeconds )
    
    DEFAULT nSeconds := 10
    
    nSeconds := nSeconds * 1000
        
    while .T.
    
      ExtraerReporteZ( oMsgItem )
            
        ThreadSleep( nSeconds )     
                        
  enddo
  
Return Nil
 

Re: StartThread NO es estable usando FiveWin ?

Posted: Wed Oct 03, 2018 2:35 pm
by vilian
Hi,
Yes, startThead works, but depend that you are using in your function (DownloadReportes())

Give a look at this link: http://www.kresin.ru/en/hrbfaq_3.html#Doc11, to understand thread better.

Re: StartThread NO es estable usando FiveWin ?

Posted: Wed Oct 03, 2018 3:03 pm
by albeiroval
Vilian,

Gracias por responder, aqui el codigo de la funcion :

Code: Select all

Function ExtraerReporteZ( oMsgItem )
    Local oQry 
    Local oError 
    Local cFechaini, cFechafin
    Local aDatos     := {}
    Local cSerial  := Serial_Fiscal()
    Local   cMessage := oMsgItem:cMsg
        
    TRY
        oQry = oSrv:FindRow( TABLA_AUTOREPORTE, "serial", cSerial, FALSE, FALSE )
        if oQry:RecCount() > 0
           aDatos := { oQry:procesado, oQry:periodo, oQry:serial, oQry:my_recno }
        endif
        oQry:End()
    CATCH   oError
      aDatos := {}
    END
    
    oMsgItem:nClrText = CLR_HRED
    oMsgItem:SetText( "DESCARGANDO REPORTES Z PERIODO DE IMPRESORA FISCAL = " + cSerial + " !!!" )
    
  if Len(aDatos) > 0
       if aDatos[1] == BFALSE 
          cFechaini := Left( aDatos[2], 6 )
          cFechafin := SubStr( aDatos[2], 8, 6 )
          if TFHKA_UploadReportesZ( cFechaini, cFechafin, FALSE )
             oSrv:Updatehash( TABLA_AUTOREPORTE, { "procesado" => BTRUE }, "my_recno="+ClipValue2Sql(aDatos[4]) )
          endif   
       endif
    endif
        
    oMsgItem:nClrText = CLR_BLACK
    oMsgItem:SetText( cMessage )
                
Return Nil
 

Re: StartThread NO es estable usando FiveWin ?

Posted: Sat Oct 06, 2018 2:52 am
by albeiroval
Amigos,

Viendo el link que me paso vilian hize cambios, pero tampoco es estable.
El programa trabaja 10 min y luego se congela y hay que cerrar el programa.
Este el codigo que probe

Code: Select all


Function main()
...
if hb_mtvm()
         hb_threadStart( @DownloadReportesZ(), oMsgItem, 30 )
      endif   

...

static Function DownloadReportesZ( oMsgItem, nSeconds )
    
    DEFAULT nSeconds := 10
    
    WHILE TRUE
    
      ExtraerReporteZ( oMsgItem )
            
        hb_idleSleep( nSeconds )    
                        
  ENDDO
  
Return Nil

 
Segun lo que he leido en el foro los Threads !! AUN NO SON ESTABLES !!
Voy a tener que trabajar con un TIMER.

Re: StartThread NO es estable usando FiveWin ?

Posted: Sat Oct 06, 2018 8:31 am
by hmpaquito
Hola,

Hasta donde yo sé los threads son estables siempre que no se incluya codigo GUI fivewin.Esto lo leí alguna vez. Hay muchos ejemplos de uso de threads sin GUIs, que según sus autores, funcionan perfectamente. Incluso el servidor http que tiene harbour en las contribs utiliza threads de forma masiva.

En alguna ocasión he necesitado algo consistente en lanzar un proceso aparte y que continue la ejecucion. Lo que hice fue una mega-chapu: re-invoco el ejecutable con un parametro que le indice que debe hacer la tarea y terminar. Esa invocación dejará resultados en una tabla que podrá ser leída por el programa llamante en el momento en que exista (aquí puede estar bien el timer). Las situaciones pueden tener diversas casuísticas. Se trataría de adaptar.

Saludos

Re: StartThread NO es estable usando FiveWin ?

Posted: Sun Oct 07, 2018 3:18 pm
by albeiroval
hmpaquito,

Gracias por responder, es LAMENTABLE que fivewin no sea compatible o estable usando threads con
harbour. Los threads son una buena herramienta para ejecutar procesos en paralelo o multitareas,
he revisado codigo en "C" y logre hacer un thread usando un mensaje en "C" pero no logre llamar con exito
un codeblock usando "hb_evalBlock(", me generaba un GPF.

Tendre que usar TIMER, que no es lo ideal pero solventare el requerimento.

Re: StartThread NO es estable usando FiveWin

Posted: Sun Oct 07, 2018 6:16 pm
by cnavarro
Bien, no es que esté utilizando de forma intensiva Multihilos en ejemplos de Fivewin, pero los que he realizado, ( incluyendo el servidor Http dentro de una ventana de Fivewin ), no me han producido ningún problema, incluso también incluyendo como prueba procesos modales en alguno de ellos, pero........., como digo no lo he probado en todos los escenarios posibles, así como tampoco conozco la forma en la que lo has implementado. Eso sí, creo recordar, que siempre los he utilizado una vez creada la ventana principal de la aplicación.
Esto me anima a dar prioridad a su implementación en FivEdit ( que ya tenía pensado hacer ), y, poder comentar mi experiencia

Re: StartThread NO es estable usando FiveWin

Posted: Sun Oct 07, 2018 9:49 pm
by albeiroval
Hola navarro,

En este post puse el codigo con las dos maneras que probe para trabajar el multihilo,
uno al crear la windows principal (en el ON INIT) y otra antes de crearlo,
usando codeblock y otra usando puntero a funcion, con ninguna de la dos me fue bien,
inclusive bloqueando y desbloqueando el proceso con mutex,
Seria interesante y de gran ayuda si puedes poner un ejemplo funcional.

Gracias.

Re: StartThread NO es estable usando FiveWin

Posted: Sun Oct 07, 2018 10:10 pm
by cnavarro
Qué versión de Fw y harbour utilizas?

Re: StartThread NO es estable usando FiveWin

Posted: Sun Oct 07, 2018 10:48 pm
by albeiroval
Navarro, yo uso fwh 17.05 y harbour 3.2.0 dev(r1801051438)

Re: StartThread NO es estable usando FiveWin

Posted: Mon Oct 08, 2018 1:25 am
by Patricio Avalos Aguirre
Hola Albeiro

prueba colocar una static en la funcion extaerreport..

Function ExtraerReporteZ( oMsgItem )
static lentre := .f.
Local oQry

if !lentre
lentre := .t.
bla
bla
lentre := .f.
endif
return..

Re: StartThread NO es estable usando FiveWin

Posted: Mon Oct 08, 2018 12:58 pm
by albeiroval
Hola patricio,

El problema no esta en si la funcion ExtraerReporteZ(...) se ejecuta o no,
la funcion se debe ejecutar cada XX segundos, por eso es que quiero usar un hilo
y no un timer

Re: StartThread NO es estable usando FiveWin

Posted: Mon Oct 08, 2018 2:09 pm
by darioflores
La ejecución de código a través de hilos tiene una serie de cuestiones a tener en cuenta, hay que reinventarse un poco en la forma de programar.

Te dejo un enlace al blog de Don Rafa Carmona, para que te hagas un poco a la idea de esas cuestiones.

http://xthefull.blogspot.com/2016/07/th ... vatos.html

Yo estoy utilizando hilos y no tengo problemas.


Un saludo.

Re: StartThread NO es estable usando FiveWin

Posted: Mon Oct 08, 2018 3:23 pm
by albeiroval
dario,

Ese link ya lo revise hace dias, en este post hablo que he usado codeblocks y funciones para crear los hilos y
los mutex para bloquear y desbloquear un hilo, que en mi caso no necesitaria usarlo ya que solo voy a manejar un (1) solo hilo,
el cual se ejecuta cada XXX tiempo.

Ya que comentas que estas usando hilos sin problema podrias poner algo del codigo que usas para ver lo siguiente :
1- Como los creas
2- Como lo invocas
3- Como los cierras

Gracias

Re: StartThread NO es estable usando FiveWin

Posted: Mon Oct 08, 2018 3:36 pm
by cnavarro
Aqui tienes un ejemplo sencillo

Code: Select all

//----------------------------------------------------------------------------//
// Programa: TESTMT01.PRG
// Autor...: Cristobal Navarro
//----------------------------------------------------------------------------//

#include "Fivewin.ch"
#include "hbthread.ch"
#include "gif.ch"

Static oPnel1

Function Main()

   local oWnd
   local oBar
   local oBtt1
   local oBtt2
   local uTh1
   local uTh2
   local uTh3
   local nPress  := 0

    DEFINE DIALOG oWnd FROM 0, 0 TO 660, 1100 TITLE "Test" PIXEL //MDI

      DEFINE BUTTONBAR oBar SIZE 48, 48 OF oWnd 2015
      DEFINE BUTTON oBtt1 PROMPT "Salir" OF oBar ACTION oWnd:End() TOOLTIP "Salir" 
      DEFINE BUTTON oBtt2 PROMPT "Test"  OF oBar ;
         ACTION ( nPress++, ;
                  uTh1 := hb_threadStart( HB_THREAD_INHERIT_PUBLIC, @WTest(), "Hello", 120, nPress ),;
                  uTh2 := hb_threadStart( HB_THREAD_INHERIT_PUBLIC, @WTest(), 333, 120, nPress ),;
                  MsgWait( "Process", "Modal", 5  )) 
   
   ACTIVATE DIALOG oWnd ;
      ON INIT ( HazPnel( oWnd ), CrearGif( oWnd ) ) ;
      VALID ( hb_threadTerminateAll(), .T. )
//                  uTh3 := hb_threadStart( HB_THREAD_INHERIT_PUBLIC, @CrearGif(), oWnd ),;
Return NIL 

//----------------------------------------------------------------------------//

Function WTest( u, nF, nPress )

   local x := 1
   if Valtype( u ) = "N"
      For x = 1 to 300 step 15
         @ nF + x, 60 + ( ( nPress - 1 ) * 110 ) SAY "Thread " + StrZero( nPress + 1, 2 ) ;
            OF oPnel1 PIXEL COLOR CLR_BLACK 
         SysRefresh()
         hb_idleSleep( 0.8 )
      Next x
   else
      For x = 1 to 300 step 15
         @ nF + x, 4 + ( ( nPress - 1 ) * 110 ) SAY "Thread " + StrZero( nPress, 2 ) ;
            OF oPnel1 PIXEL COLOR CLR_RED
         SysRefresh()
         hb_idleSleep( 0.8 )
      Next x
   endif

Return nil

//----------------------------------------------------------------------------//

Function HazPnel( oWnd )

   @ 50, 400 PANEL oPnel1 OF oWnd SIZE 600, 550
   oPnel1:SetColor( CLR_BLACK, CLR_YELLOW )
   
Return oPnel1

//----------------------------------------------------------------------------//

Function CrearGif( oDlg )
   
   local oGif
   @ 60, 10 GIF oGif FILE "..\gifs\matrix.gif" OF oDlg SIZE 100, 100 //ADJUST //

Return nil

//----------------------------------------------------------------------------//
 
Si lo pruebas y es ESTABLE, por favor, coméntalo en el foro.
Aunque como he dicho anteriormente, y el compañero Dario creo que lo ha expresado también muy bien, depende del objetivo para el que lo uses y cómo lo implementes