Trabajado con Future's
Publicado: Lun Abr 20, 2020 4:24 pm
Buenas Xailer Team, estoy probando ya los nuevos Futures de la beta de Xailer 7 y dada la lógica falta de documentación, me encuentro con algunas dudas y problemas.
Pienso sustituir todos mis hilos por Futures para ganar en simplicidad de código y control pero....
1.- Si los futures se apilan para ser ejecutados en otro hilo de forma secuencial, como puedo saber
a) Si han finalizado todos, por que si intento salir de la aplicación antes de acabar estos, la aplicación da un lógico error
b) Se puede saber la lista de los que quedan por ejecutar? Se podrá asignar un nombre a cada uno para saber cual está haciendo y cuales quedan? He modificado el Sample Futures.Prg y cada Future me devuelve un :TaskCount() de 1, quizás deberia de instanciar para ello un solo Appdata:Future por aplicación y cargar a el todos los futures.
2.- Si hago un AWAIT INLINE {||SYNCHRO FUNCTION ¿se puede establecer un OnComplete? o no hay manera salvo haciendo un objeto instanciado con nombre como oFuture := TFuture():New()
3.- Además de OnComplete y OnError no veo otros eventos. No sería útil un evento OnStart por ejemplo, justo al contrario que OnComplete para inicializar objetos por ejemplo? No es necesario por que se puede hacer antes de llamar al Future pero...
4.- Si da un error la aplicación mientras está ejecutando un Future sale el error en pantalla pero se bloquea todo, lo he probado con el Sample Futures.Prg poniendo un error al final del tercero y poniendo en marcha los otros 2 pongo en marcha el tercero y zasca.
5.- Por último un error, he creado un Future para realizar las copias de seguridda de las BBDD de la aplicación al entrar (antes lo hacia con tThread) y ok funciona bien, es un proceso pesado y entre tanto puedo hacer otras cosas, esa es la idea. Pero resulta que tengo varios timer que refrescan diferentes cosas y si saltan algunos de ellos provocan errores curiosos, este es el primero y ando detras de otro que no se produce siempre.
______________________ Información detallada del error ______________________
Subsistema: WINOLE
Código de error: 1007
Estado: .F.
Descripción: No se puede hacer una llamada de salida desde la aplicación que está ejecutando una llamada sincrónica de entrada. (0x8001010D)
Operación: CONNECTSERVER
Argumentos:
Fichero: SWbemLocator
Código error SO: -2147352567
Pila de llamadas:
REALMEMORY (1436)
WIDGETSYSMETERREFRESH (1046)
(b)TFRMMAIN_FORMINITIALIZE (125)
TTIMER:ONTIMER (0)
(b)XTIMER (43)
TTIMER:WMTIMER (0)
WIN_OLEAUTO:RUN (0)
TSQLSTRUCTURE:DAILYBACKUP (3151)
(b)TFRMMAIN_PRUEBAASYNC (1600)
TFUTURE:RUNSYNCHRO (244)
(b)XFUTURE (51)
TFUTURE:WMXAILER (0)
RUNFORM (0)
TAPPLICATION:RUN (289)
MAIN (16)
Esta es la función que ejecuta, aunque me pasa en otras también, parace que no se puede acceder al API de Windows mientras está el future en marcha.
//Escanea la memoria del equipo y devuelve sus características en un array de 1 línea
//Devuelve tamaño_mem_real, tamaño_libre_mem_real, tamaño_mem_virtual, tamaño_libre_mem_virtual
Function RealMemory()
LOCAL oScriptObj, oWmiService, aRM := {}, oRM, aInfo:={}
oScriptObj = CREATEOBJECT( "wbemScripting.SwbemLocator" )
oWmiService = oScriptObj:ConnectServer() <<======Aqui se produce el error ¿?¿?¿?¿?¿??¿
aRM = oWmiService:ExecQuery("Select * from Win32_OperatingSystem")
for each oRM in aRM
AAdd(aInfo,{Val(oRM:TotalVisibleMemorySize),Val(oRM:FreePhysicalMemory) ,Val(oRM:TotalVirtualMemorySize),Val(oRM:FreeVirtualMemory)})
next
RETURN aInfo
Muchas gracias.
Pienso sustituir todos mis hilos por Futures para ganar en simplicidad de código y control pero....
1.- Si los futures se apilan para ser ejecutados en otro hilo de forma secuencial, como puedo saber
a) Si han finalizado todos, por que si intento salir de la aplicación antes de acabar estos, la aplicación da un lógico error
b) Se puede saber la lista de los que quedan por ejecutar? Se podrá asignar un nombre a cada uno para saber cual está haciendo y cuales quedan? He modificado el Sample Futures.Prg y cada Future me devuelve un :TaskCount() de 1, quizás deberia de instanciar para ello un solo Appdata:Future por aplicación y cargar a el todos los futures.
2.- Si hago un AWAIT INLINE {||SYNCHRO FUNCTION ¿se puede establecer un OnComplete? o no hay manera salvo haciendo un objeto instanciado con nombre como oFuture := TFuture():New()
3.- Además de OnComplete y OnError no veo otros eventos. No sería útil un evento OnStart por ejemplo, justo al contrario que OnComplete para inicializar objetos por ejemplo? No es necesario por que se puede hacer antes de llamar al Future pero...
4.- Si da un error la aplicación mientras está ejecutando un Future sale el error en pantalla pero se bloquea todo, lo he probado con el Sample Futures.Prg poniendo un error al final del tercero y poniendo en marcha los otros 2 pongo en marcha el tercero y zasca.
5.- Por último un error, he creado un Future para realizar las copias de seguridda de las BBDD de la aplicación al entrar (antes lo hacia con tThread) y ok funciona bien, es un proceso pesado y entre tanto puedo hacer otras cosas, esa es la idea. Pero resulta que tengo varios timer que refrescan diferentes cosas y si saltan algunos de ellos provocan errores curiosos, este es el primero y ando detras de otro que no se produce siempre.
______________________ Información detallada del error ______________________
Subsistema: WINOLE
Código de error: 1007
Estado: .F.
Descripción: No se puede hacer una llamada de salida desde la aplicación que está ejecutando una llamada sincrónica de entrada. (0x8001010D)
Operación: CONNECTSERVER
Argumentos:
Fichero: SWbemLocator
Código error SO: -2147352567
Pila de llamadas:
REALMEMORY (1436)
WIDGETSYSMETERREFRESH (1046)
(b)TFRMMAIN_FORMINITIALIZE (125)
TTIMER:ONTIMER (0)
(b)XTIMER (43)
TTIMER:WMTIMER (0)
WIN_OLEAUTO:RUN (0)
TSQLSTRUCTURE:DAILYBACKUP (3151)
(b)TFRMMAIN_PRUEBAASYNC (1600)
TFUTURE:RUNSYNCHRO (244)
(b)XFUTURE (51)
TFUTURE:WMXAILER (0)
RUNFORM (0)
TAPPLICATION:RUN (289)
MAIN (16)
Esta es la función que ejecuta, aunque me pasa en otras también, parace que no se puede acceder al API de Windows mientras está el future en marcha.
//Escanea la memoria del equipo y devuelve sus características en un array de 1 línea
//Devuelve tamaño_mem_real, tamaño_libre_mem_real, tamaño_mem_virtual, tamaño_libre_mem_virtual
Function RealMemory()
LOCAL oScriptObj, oWmiService, aRM := {}, oRM, aInfo:={}
oScriptObj = CREATEOBJECT( "wbemScripting.SwbemLocator" )
oWmiService = oScriptObj:ConnectServer() <<======Aqui se produce el error ¿?¿?¿?¿?¿??¿
aRM = oWmiService:ExecQuery("Select * from Win32_OperatingSystem")
for each oRM in aRM
AAdd(aInfo,{Val(oRM:TotalVisibleMemorySize),Val(oRM:FreePhysicalMemory) ,Val(oRM:TotalVirtualMemorySize),Val(oRM:FreeVirtualMemory)})
next
RETURN aInfo
Muchas gracias.