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