AYUDA EN LÍNEA
 WINDEVWEBDEV Y WINDEV MOBILE

Este contenido se ha traducido automáticamente.  Haga clic aquí  para ver la versión en inglés.
Ayuda / WLanguage / Funciones WLanguage / Funciones estándar / Funciones de gestión de procesos / Tareas paralelas
  • Presentación
  • Principio
  • ¿Cómo proceder?
  • Principio
  • Crear y ejecutar una tarea paralela
  • La palabra clave de MyParallelTask
  • Esperar la ejecución de la tarea y recuperar el valor de retorno
  • Gestión de la secuencia de tareas paralelas
  • Manejo de los controles desde una tarea paralela
  • Ejemplo: Acelerar los procesos
  • Acelerar los procesos: cálculo estadístico
  • Ejemplo: Mejorar la reactividad de la aplicación
  • Mejorar la reactividad de la aplicación
  • Actualización de la GUI mediante una tarea de continuación
  • Actualizando el GUI a través de una corrida de Procedure en el Thread principal
WINDEV
WindowsLinuxUniversal Windows 10 AppJavaReportes y ConsultasCódigo de Usuario (UMC)
WEBDEV
WindowsLinuxPHPWEBDEV - Código Navegador
WINDEV Mobile
AndroidWidget Android iPhone/iPadIOS WidgetApple WatchMac CatalystUniversal Windows 10 App
Otros
Procedimientos almacenados
Presentación
Los ordenadores son cada vez más potentes. Los ordenadores tienen potentes procesadores con varios núcleos.
Para mejorar el rendimiento de las aplicaciones y trabajar con el máximo número de núcleos del ordenador, ahora tiene la posibilidad de dividir los procesos en una lista de subprocesos (llamados tareas) y ejecutarlos en paralelo en lugar de secuencialmente.
Una tarea es una Procedure a ejecutar que puede esperar parámetros y que puede devolver un resultado. Estas tareas serán ejecutadas por el equipo en uno o más hilos según la disponibilidad de el equipo.
Una tarea puede dividirse en varias subtareas.
¿Cuál es el beneficio de las tareas paralelas?
Las tareas paralelas son useful a:
  • acelera el tiempo de aplicación de Process mediante el paralelismo: varios procesos se ejecutan en paralelo en lugar de ejecutarse secuencialmente: se mejora la velocidad de la aplicación.
    Un ejemplo sencillo: iniciar un cálculo estadístico para enviar y recibir correos electrónicos en cada correo electrónico Address de la base de datos. Si el cálculo estadístico de un correo electrónico Address toma un segundo y si la base de datos contiene 200 000 correos electrónicos Address es, el cálculo toma más de dos días.
    Para ir más rápido, tienes la capacidad de iniciar una tarea paralela por cada correo electrónico que Address encontró.
    Este ejemplo se presenta en Ejemplo: Acelerar los procesos.
  • mejorar la reactividad de la aplicación: varios procesos largos y de bloqueo se ejecutan en paralelo en lugar de ejecutarse secuencialmente: el usuario no se siente atrapado.
    Un ejemplo sencillo: Un control Tabla muestra una lista de contactos cuya foto se carga desde un INTERNET Address. Para cada contacto, la aplicación realiza una solicitud de INTERNET (que desencadena una desaceleración).
    Para que el control Tabla se llene sin ser bloqueado, el proceso de visualización de fila inicia una tarea paralela que se usa para iniciar la solicitud de INTERNET y para actualización la GUI si es necesario.
    Este ejemplo se presenta en Ejemplo: Mejorar la reactividad de la aplicación.
Principio
Para gestionar las tareas paralelas, WLanguage propone:
  • una variable de tipo ParallelTask. Este tipo de Variable se utiliza para manipular una tarea paralela. Este tipo de Variable no puede ser usado para modificar las características de una tarea paralela.
  • funciones de gestión de tareas (ParallelTask*).
Observación: También tiene la posibilidad de utilizar el Descripción de ParallelTask Variable. Este tipo de Variable sólo puede ser usado para describir una tarea paralela. Una vez definida la tarea paralela, sus características no pueden modificarse.
¿Cómo proceder?

Principio

Para implementar una gestión de tareas paralelas, debe:
  1. Crear y ejecutar una tarea paralela.
  2. Esperar la ejecución de la tarea y recuperar el valor de retorno.
  3. Gestionar (si es necesario) la secuencia de tareas paralelas.
  4. Manejar (si es necesario) los controles de una tarea paralela..

Crear y ejecutar una tarea paralela

Una tarea paralela debe estar asociada a una ParallelTask Variable.
Se pueden utilizar varios métodos para declarar un ParallelTask Variable:
  • Declaración simple. La tarea paralela se describe durante su ejecución con ParallelTaskExecute:
    // Declares a variable to handle a parallel task
    t is ParallelTask
    // Run and describe the parallel task
    t = ParallelTaskExecute(Proc, ("First parameter", 2))
  • Declaración y description de la tarea paralela. A continuación, la tarea paralela es ejecutada por ParallelTaskExecute.
    // Builds a parallel task
    t is ParallelTask(Proc, ("First parameter", 2))
    // Triggers the execution of parallel task
    ParallelTaskExecute(t)
Observación: Al describir la tarea paralela, tiene la capacidad de especificar:
  • el Procedure para dirigir.
  • los parámetros esperados por la Procedure.
  • el modo de tiempo de ejecución de la tarea paralela: gestión de los contextos HFSQL e interacciones con el principal Thread.

La palabra clave de MyParallelTask

MyParallelTask se utiliza para gestionar la tarea paralela actual y descubrir sus propiedades. Esto le permite acceder a la información sobre la tarea paralela actual en el código ejecutado por una tarea paralela. Las propiedades accesibles son las de las variables de ParallelTask:
Nombre de la propiedadTipo utilizadoEfecto
Canceladobooleano
  • True si se cancela la tarea,
  • False en caso contrario.
Esta propiedad es de solo lectura.
Concluidobooleano
  • True si se completó la tarea,
  • False en caso contrario.
Esta propiedad es de solo lectura.
EstadoConstante de tipo IntegerStatus de la tarea:
  • ptsCanceled: la tarea paralela se cancela (ParallelTaskCancel).
  • ptsCancellationRequested: se ha realizado una solicitud de cancelación en la tarea paralela (ParallelTaskRequestCancellation).
  • ptsWaitingExecution: la tarea paralela está a la espera de ser ejecutada.
  • ptsWaitingPrevious: La tarea paralela espera la ejecución de una tarea paralela anterior..
  • ptsExecutionInProgress: la tarea paralela se está ejecutando actualmente.
  • ptsNotScheduled: la tarea paralela no está programada.
  • ptsCompleted: la tarea paralela ha terminado.
Esta propiedad es de solo lectura.
IdentificadorIntegroIdentificador de tareas. Este identificador puede ser usado para propósitos de depuración, por ejemplo.
Esta propiedad es de solo lectura.
ReturnedValueValor devuelto por la tarea. Atención:
  • Si la tarea aún está en curso, la ReturnedValue Property espera el final de la tarea
  • Si la tarea se completa sin error fatal, la Property devuelve los valores de retorno de la Procedure de la tarea.
Esta propiedad es de solo lectura.

Esperar la ejecución de la tarea y recuperar el valor de retorno

Se pueden iniciar varias tareas paralelas al mismo tiempo. Tienes la capacidad de esperar la ejecución de una o más tareas paralelas antes de ejecutar un Process:
ParallelTaskWaitEspera la ejecución de una tarea paralela.
ParallelTaskWaitAllEspera al final de la ejecución de todas las tareas paralelas que se encuentran en una array.
La propiedad ValeurRenvoyée de la variable ParallelTask obtiene el valor devuelto por el Procedure ejecutado por la tarea paralela.
Atención: Este valor sólo está disponible si la tarea paralela ha finalizado.. Si la tarea está en progreso, la llamada a este Property se bloquea hasta el final de la tarea.

Gestión de la secuencia de tareas paralelas

Se pueden iniciar varias tareas paralelas al mismo tiempo. Tiene la capacidad de definir la secuencia de tareas paralelas: una tarea puede esperar al final de la ejecución de una o más tareas antes de ejecutarse. Las siguientes funciones se utilizan para definir una tarea de continuación:
ParallelTaskExecuteAfterIndica una tarea paralela de continuación que se ejecutará cuando finalice una de las tareas paralelas especificadas.
ParallelTaskExecuteAfterAllIndica una tarea paralela de continuación que se ejecutará cuando todas las tareas de un array de tareas paralelas hayan finalizado.
ParallelTaskExecuteAfterOneIndica una tarea paralela de continuación que se ejecutará una vez finalizada la primera tarea de un array de tareas paralelas.
Observación: En una tarea de continuación, puede:

Manejo de los controles desde una tarea paralela

No puede actuar en la interfase desde una tarea paralela. Por lo tanto, no puedes asignar un control, llenar una tabla o control Looper.
Sólo una tarea definida por la constante ptoMainThread puede ser ejecutada en el Thread principal y puede actualizar los controles si es necesario.
Observación: También puede utilizar ExecuteMainThread para ejecutar una visualización específica Procedure desde la tarea paralela.
Estos dos métodos se utilizan en el ejemplo Mejorar la reactividad de la aplicación presentado en este Page.
Ejemplo: Acelerar los procesos

Acelerar los procesos: cálculo estadístico

Una aplicación utiliza el procedimiento CalculateStatEmailAddress para realizar cálculos estadísticos sobre las operaciones de envío y recepción de cada dirección de correo electrónico del archivo CUSTOMER. Este Procedure toma como parámetro el correo electrónico Address y calcula todas las estadísticas de este Address.
Si el cálculo estadístico en un correo electrónico Address toma un segundo y si la base de datos contiene 200 000 correos electrónicos Address es, el cálculo toma más de dos días (200 000 segundos).
Para ir más rápido, tienes la capacidad de iniciar una tarea paralela por cada correo electrónico que Address encontró.
Ejemplo de código:
  • Código inicial (antes de utilizar tareas paralelas):
    nAddressesInError is int
     
    HourGlass(True)
    ChronoStart()
    // Browses the list of customers
    FOR EACH Customer
    // Starts the statistical calculation on the email address
    IF CalculateStatEmailAddress(Customer.Email, 1) = False THEN
    nAddressesInError++
    END
    END
    HourGlass(False)
    STC_Result_1 = StringBuild("Result: %1 addresses in error", nAddressesInError)
    Info("Process completed", DurationToString(ChronoEnd(), "MMm SSs CCC"))
  • Code thai está usando las tareas paralelas:
    nAddressesInError is int
    arrTasks is array of ParallelTasks
    ATask is ParallelTask
     
    HourGlass(True)
    ChronoStart()
    // Browses the list of customers
    FOR EACH Customer
    // Starts the statistical calculation on the email address via a parallel task
    ATask = ParallelTaskExecute(CalculateStatEmailAddress, ...
    (Customer.Email, 1), ptoLightCopyHFSQLContext)
    // Stores this task in an array
    Add(arrTasks, ATask)
    END
     
    // Waits for the end of task execution
    ParallelTaskWaitAll(arrTasks)
    HourGlass(False)
     
    // Browses the tasks
    FOR EACH ATask OF arrTasks
    IF ATask..ReturnedValue = False THEN
    nAddressesInError++
    END
    END
    STC_Result_2 = StringBuild("Result: %1 addresses in error", nAddressesInError)
    Info("Process completed", DurationToString(ChronoEnd(), "MMm SSs CCC"))
Ejemplo: Mejorar la reactividad de la aplicación

Mejorar la reactividad de la aplicación

Un control Tabla muestra una lista de contactos cuya foto se carga desde un INTERNET Address. Para cada contacto, la aplicación realiza una solicitud de INTERNET (que desencadena una desaceleración).
Para mejorar la reactividad de la aplicación y obtener una interfaz gráfica de usuario fluida, se inicia una tarea paralela en el Process para mostrar un fila de control Tabla. Esta tarea paralela:
  • recibe el identificador de Contact en el prameter.
  • realiza la solicitud de INTERNET a get el Image.
  • recupera el Image.
  • llama una función para actualizar el control Tabla.
Veamos dos códigos diferentes para este ejemplo: estos dos códigos presentan dos métodos diferentes para actualizar la GUI:

Actualización de la GUI mediante una tarea de continuación

Al no ser posible la actualización de la interfaz desde una tarea paralela ejecutada en el Thread principal, se implementa una tarea de continuación específica para la visualización mediante ParallelTaskExecuteAfter. Uno de los parámetros pasados a la tarea de continuación corresponde al valor devuelto por la tarea paralela principal.. Para especificar este parámetro, todo lo que tiene que hacer es utilizar la función ReturnedValuePreviousTask descriptor.
Ejemplo de código:
  • Código para mostrar un tabla fila:
    // If the photo is not filled yet
    IF COL_Photo ~= "" THEN
    // Positions the hourglass image while waiting for the photo to be retrieved from "Internet"
    COL_Photo = IMG_Hourglass
    // Starts retrieving the photo in a parallel task
    MyTaskFindImage is ParallelTask = ParallelTaskExecute(FindImage, ...
    (COL_CustomerNum), ptoLightCopyHFSQLContext)
    // Starts displaying the image in a continuation task
    // that interacts with the interface
    ParallelTaskExecuteAfter(MyTaskFindImage, DisplayImage, ...
    (COL_CustomerNum, ReturnedValuePreviousTask), ptoMainThread)
    END
  • Código de "FindImage" Procedure: Este Process se usa para recuperar el Image.
    PROCÉDURE FindImage(LOCAL nCustomerID is 8-byte int)

    // Retrieve the photo
    Result1 is boolean = HTTPRequest("http://Linkedin.com/photos/id=" + ID)
    IF Result1 = True THEN
    bufPhoto is Buffer = HTTPGetResult()
    bufPhoto = fLoadBuffer(fExeDir() + fSep() + "Photos\" + ID + ".jpg")
    END

    RESULT bufPhoto
  • Código de "DisplayImage" Procedure: Este Procedure se usa para mostrar el Image en el tabla.
    PROCEDURE DisplayImage(nCustomerID is 8-byte int, sPhotoPath is string)
    // Finds the customer in the table
    nIndex is int = TableSearch("WIN_MENU.TABLE_Customer.COL_CustomerNum", nCustomerID)
    IF nIndex > 0 THEN
    // Displays the customer photo
    WIN_Menu.TABLE_Customer.COL_Photo[nIndex] = sPhotoPath
    END

Actualizando el GUI a través de una corrida de Procedure en el Thread principal

No se puede acceder a los controles de la ventana desde una tarea paralela. Para mostrar la imagen, el programa DisplayImage Procedure es ejecutado por ExecuteMainThread. Esta función obliga a la ejecución de la Procedure en la thread principal.
También tienes la capacidad de indicar al DisplayImage Procedure que siempre se ejecutará en el Thread principal. Lo único que tienes que hacer es pulsar el botón en la barra del editor de código y marcar "Ejecutar en el Thread principal".
Ejemplo de código:
  • Código para mostrar un tabla fila:
    // If the photo is not filled yet
    IF COL_Photo ~= "" THEN
    // Positions the hourglass image while waiting for the photo to be retrieved from "Internet"
    COL_Photo  = IMG_Hourglass
    // Starts retrieving the photo in a parallel task
    MyTaskFindImage is ParallelTask = ParallelTaskExecute(FindImage, ...
    (COL_CustomerNum), ptoLightCopyHFSQLContext)
    END
  • Código de "FindImage" Procedure: Este Process se usa para recuperar el Image.
    PROCÉDURE FindImage(LOCAL nCustomerID is 8-byte int)

    // Retrieve the photo
    Result1 is boolean = HTTPRequest("http://Linkedin.com/photos/id=" + ID)
    IF Result1 = True THEN
    bufPhoto is Buffer = HTTPGetResult()
    bufPhoto = fLoadBuffer(fExeDir() + fSep() + "Photos\"+ ID + ".jpg")
    END

    // Calls the procedure to display the image
    ExecuteMainThread(DisplayImage, nCustomerID, bufPhoto)
  • Código de "DisplayImage" Procedure: Este Procedure se usa para mostrar el Image en el tabla.
    PROCEDURE DisplayImage(nCustomerID is 8-byte int, sPhotoPath is string)
    // Finds the customer in the table
    nIndex is int = TableSearch("WIN_MENU.TABLE_Customer.COL_CustomerNum", nCustomerID)
    IF nIndex > 0 THEN
    // Displays the customer photo
    WIN_Menu.TABLE_Customer.COL_Photo[nIndex] = sPhotoPath
    END
Versión mínima requerida
  • Versión 20
Esta página también está disponible para…
Comentarios
Haga clic en [Agregar] para publicar un comentario

Última modificación: 27/01/2023

Señalar un error o enviar una sugerencia | Ayuda local