Patrones avanzados
Patrones de uso comunes para progress reporting, tareas paralelas, eventos, manejo de errores, cancelacion y encadenamiento de tareas.
1. Progress reporting
Actualiza loTask.Progress (0-100) desde dentro del procedimiento de tarea. Lee el valor desde el hilo principal usando un Timer.
* Inside task procedure (MyTasks.prg):
PROCEDURE LongImport(loParams, loTask)
LOCAL i, lnTotal
lnTotal = loParams.rowCount
FOR i = 1 TO lnTotal
* ... process row i ...
loTask.Progress = INT((i / lnTotal) * 100)
NEXT
loTask.Result = TRANSFORM(lnTotal) + " rows imported."
ENDPROC * In main thread -- Timer event (interval 500 ms):
PROCEDURE Timer1_Timer
oProgressBar.Value = loTask.Progress
IF loTask.Status == "Done" OR loTask.Status == "Failed"
Timer1.Enabled = .F.
ENDIF
ENDPROC 2. Tareas en paralelo con RunAll
RunAll ejecuta un array de nombres de procedimiento en paralelo, hasta el limite de MaxWorkers. Retorna un array de objetos Task.
LOCAL loCore, laProcs[3], loResults
loCore = CREATEOBJECT("FoxCore.FoxCoreClass")
loCore.MaxWorkers = 3
laProcs[1] = "Task_ImportFile"
laProcs[2] = "Task_GenerateReport"
laProcs[3] = "Task_SendEmails"
loResults = loCore.RunAll(@laProcs)
* loResults is an array of Task objects, one per procedure
? loResults[1].Status
? loResults[2].Status
? loResults[3].Status 3. Callbacks de eventos
Asigna el nombre de un procedimiento (como string) a OnComplete, OnFailed o OnProgress antes de llamar a Run(). FoxCore invoca el procedimiento en el hilo principal cuando ocurre el evento.
LOCAL loCore, loParams, loTask
loCore = CREATEOBJECT("FoxCore.FoxCoreClass")
loParams = CREATEOBJECT("Empty")
ADDPROPERTY(loParams, "filePath", "C:dataimport.csv")
loTask = loCore.Run("Task_ImportCSV", loParams)
loTask.OnComplete = "HandleTaskDone"
loTask.OnFailed = "HandleTaskError"
loTask.OnProgress = "HandleProgress"
* ...
PROCEDURE HandleTaskDone(loTask)
MESSAGEBOX("Done: " + loTask.Result)
ENDPROC
PROCEDURE HandleTaskError(loTask)
MESSAGEBOX("Failed: " + loTask.Error)
ENDPROC
PROCEDURE HandleProgress(loTask)
oProgressBar.Value = loTask.Progress
ENDPROC 4. Manejo de errores
Si el procedimiento de tarea lanza una excepcion no capturada, el Task pasa a Status="Failed" y loTask.Error contiene el mensaje. Verifica siempre el estado antes de leer Result.
loCore.WaitFor(loTask, 10000)
DO CASE
CASE loTask.Status == "Done"
? "Result: " + loTask.Result
CASE loTask.Status == "Failed"
MESSAGEBOX("Error: " + loTask.Error, 48, "Task Failed")
CASE loTask.Status == "Cancelled"
? "Task was cancelled."
ENDCASE 5. Cancelacion
Llama a loCore.Cancel(loTask) para solicitar la cancelacion. El Task pasa a Status="Cancelled". La tarea debe verificar el estado periodicamente si quiere responder rapidamente.
* Request cancellation from main thread:
loCore.Cancel(loTask)
* Inside the task procedure -- check periodically:
PROCEDURE Task_LongProcess(loParams, loTask)
LOCAL i
FOR i = 1 TO 1000
IF loTask.Status == "Cancelled"
EXIT
ENDIF
* ... do work ...
loTask.Progress = i / 10
NEXT
IF loTask.Status != "Cancelled"
loTask.Result = "Completed."
ENDIF
ENDPROC 6. Tareas secuenciales
Usa WaitFor() para encadenar tareas: la segunda tarea recibe el resultado de la primera como parametro. Este patron es seguro solo fuera de eventos de UI.
LOCAL loCore, loParams1, loParams2, loTask1, loTask2
loCore = CREATEOBJECT("FoxCore.FoxCoreClass")
loParams1 = CREATEOBJECT("Empty")
ADDPROPERTY(loParams1, "source", "https://api.example.com/data")
* Step 1: Fetch remote data
loTask1 = loCore.Run("Task_FetchData", loParams1)
loCore.WaitFor(loTask1, 15000)
IF loTask1.Status == "Done"
* Step 2: Process the fetched data
loParams2 = CREATEOBJECT("Empty")
ADDPROPERTY(loParams2, "data", loTask1.Result)
loTask2 = loCore.Run("Task_ProcessData", loParams2)
loCore.WaitFor(loTask2, 10000)
? loTask2.Result
ELSE
? "Fetch failed: " + loTask1.Error
ENDIF Siguiente: Referencia API ->