flex user-interface

Flex equivalente de ProcessMessages y UI insensible durante bucles largos



user-interface (5)

Encuentro que la IU de mi aplicación Flex deja de responder durante ciclos de procesamiento muy largos (decenas de segundos). Por ejemplo, al procesar archivos XML muy grandes y hacer algo por elemento ...

¿Hay un equivalente de "ProcessMessages"? Es decir, ¿una llamada que le indicaría a Flex que siga respondiendo a los eventos de IU, incluso en el medio de un bucle largo, para que la IU no deje de responder?

Soy consciente de que Flex tiene un solo hilo de rosca por diseño . Es exactamente por eso que estoy buscando algo como ProcessMessages () - una función que permite que las aplicaciones reentrantes de un solo subproceso (como en VB, o aplicaciones C ++ basadas en bucles de mensajes de un solo hilo) permanezcan receptivas durante las operaciones largas.

Resumen de respuestas

  1. No hay funciones HandleEvents() como HandleEvents() o ProcessMessages() en Flex.
  2. El uso de algún tipo de mecanismo de devolución de llamada para procesar iterativamente trozos de un proceso de computación largo, mientras se cede al tiempo de ejecución entre fragmentos, lo que permite que responda, es la única forma de mantener una interfaz de usuario receptiva durante cálculos largos.
  3. Las formas de lograr lo anterior son:
    1. Usando el evento enterFrame , que se llama cuando la capa de "película" Flash debajo de la aplicación Flex actualiza su marco (que es algo así como 20 fps).
    2. Usando un temporizador.
    3. Utilizando UIComponent.callLater() que programa el trabajo para hacerse "más tarde". (como dicen los documentos: Queues a function to be called later. Before each update of the screen, Flash Player or AIR calls the set of functions that are scheduled for the update.
    4. Usar eventos de mouse / teclado activados intencionalmente para crear pseudo "subprocesos de trabajo", como en este ejemplo .

Si hay más sugerencias, o si omití algo, siéntete libre de editar esta (ahora) pieza de wiki.


Actionscript tiene un diseño único, ninguna cantidad de respuestas downvoting cambiará eso.

Para la compatibilidad, lo mejor es intentar dividir el procesamiento en fragmentos más pequeños y realizar el procesamiento de forma iterativa.

Si realmente necesita enhebrarlo, puede hacerlo en Flash Player 10 utilizando filtros Pixel Bender . Estos se ejecutarán en un hilo separado y pueden darle una devolución de llamada una vez que hayan terminado.
Creo que son muy adecuados para las tareas de procesamiento "hardcore", por lo que pueden adaptarse a su propósito. Sin embargo, pondrán toda una serie de demandas en su código, por lo que es mejor que haga pequeños "cubos" de computación de todos modos.


El modelo de proceso para ActionScript tiene un solo subproceso, por lo que la respuesta es no. La mejor apuesta es posponer a una tarea asíncrona en el servidor si puede, o abrir un cursor de espera mientras se ejecuta su bucle largo, o dividir el proceso en algunas piezas más pequeñas que no sean tan intrusivas para la UI, o realizar el tareas de larga ejecución en un momento en que es menos probable que el usuario sienta el efecto (inicio de la aplicación, por ejemplo).


El problema es que Flash tiene una sola hebra, es decir, hasta que se ejecuta una parte del código, no se puede realizar ningún otro procesamiento. De alguna manera tendrá que dividir el procesamiento en fragmentos más pequeños y ejecutar estos fragmentos, por ejemplo, en el evento enterFrame .

Editar : me temo que la votación negativa de esta (o la respuesta de Simon) no cambia el hecho de que esto no es factible en AS3. Lee este artículo para obtener más información sobre el problema. El artículo también incluye una simple "biblioteca" llamada PseudoThread, que ayuda a ejecutar cálculos de fondo largos. Sin embargo, usted todavía tiene que dividir el problema en pedazos más pequeños.


No hay una funcionalidad equivalente en Flash Player. Por diseño, Flash Player alterna entre representación en la pantalla y luego ejecuta todo el código para cada fotograma. El uso de eventos Event.ENTER_FRAME en objetos de visualización u objetos de Timer otros lugares es la mejor opción para dividir cálculos muy largos.

Vale la pena señalar que algunos eventos en ActionScript tienen una función updateAfterEvent() con la siguiente descripción:

Indica a Flash Player o al tiempo de ejecución de AIR que procese después de que se complete el procesamiento de este evento, si la lista de visualización se ha modificado.

En particular, TimerEvent , MouseEvent y KeyboardEvent admiten updateAfterEvent() . Puede haber otros, pero esos son los que encontré con una búsqueda rápida.


Puedo decirles definitivamente que a partir de Flex 3, no hay una construcción incorporada similar a la funcionalidad de ProcessMessages que está describiendo.

La forma más común de evitar esto es dividir el trabajo que está procesando en una cola de tareas de "trabajador" y un "administrador de trabajador" para controlar la cola. A medida que cada "trabajador" completa su procesamiento, el administrador de colas del trabajador saca al siguiente trabajador de la cola y lo ejecuta en una callLater() a callLater() . Esto tendrá un efecto similar al "ceder al hilo principal" y permitirá a su IU recibir eventos y ser receptivos, al mismo tiempo que permite que el procesamiento continúe cuando se devuelve el control al trabajador.

Una vez que tenga esto funcionando, puede hacer algunas pruebas y crear perfiles para averiguar si su aplicación puede salirse con la suya ejecutando una ejecución de múltiples trabajadores antes de invocar a callLater() y encapsular esta lógica dentro del administrador de cola de trabajador. Por ejemplo, en nuestra implementación de este patrón (con unos pocos cientos de trabajadores en cola), pudimos hacer el procesamiento más rápido con un rendimiento percibido comparable mediante la ejecución de 4 trabajadores antes de "ceder al hilo principal" con callLater() , pero esto es totalmente dependiente del alcance y la naturaleza del trabajo que están realizando sus trabajadores.