Пользовательский интерфейс Flash заблокирован во время flex rpc.soap.Operation :: send - PullRequest
3 голосов
/ 19 февраля 2010

У меня есть Flash UI, который периодически вызывает сервер, чтобы получить обновленную информацию. Вызов использует класс rpc.soap.Operation гибкой SDK. Это выглядит примерно так:

var wsOperation:Operation = Operation(webService.getOperation(SomeOperation));              
wsOperation.addEventListener("fault", wsError);
wsOperation.addEventListener("result", wsResult);           
wsOperation.send(...some params);

Этот вызов получает некоторые данные из базы данных SQL. Я рассчитал время вызова прямо перед отправкой в ​​начало функции wsResult на ~ 4 секунды. В течение этого времени мой интерфейс не обновлялся. Это заморожено / не отвечает.

Теперь я знаю, что Flash однопоточный / асинхронный, поэтому я не уверен, почему это происходит. Я вижу, что функция send (..) возвращает AsyncToken, который я не использую. Может ли это быть как-то связано с этим?

Любые другие идеи относительно того, почему это происходит, приветствуются. Спасибо.


Я до сих пор не нашел приемлемого решения для этого. Кажется смешным, что мне понадобится псевдо-поток, чтобы получить флэш-память для обновления интерфейса во время 4-секундного вызова. Я задаюсь вопросом, может быть, разбор ответа мыла может занять много времени. Если будет много обработки, будет ли Flash задерживать обновление пользовательского интерфейса на неопределенное время?

1 Ответ

3 голосов
/ 19 февраля 2010

Вы получите зависание пользовательского интерфейса во Flash, потому что он однопоточный. Тем не менее, вы можете выполнить псевдопоточность примерно так:

package
{
 import flash.display.DisplayObjectContainer;
 import flash.events.Event;
 import flash.events.EventDispatcher;
 import flash.events.KeyboardEvent;
 import flash.events.MouseEvent;
 import flash.utils.getTimer;
 import mx.core.UIComponent;
 import mx.managers.ISystemManager;

 public class PseudoThread extends EventDispatcher
 {
     public function PseudoThread(sm:ISystemManager, threadFunction:Function, threadObject:Object)
     {
         fn = threadFunction;
         obj = threadObject;

         // add high priority listener for ENTER_FRAME
         sm.stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 100);
         sm.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
         sm.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);

         thread = new UIComponent();
         sm.addChild(thread);
         thread.addEventListener(Event.RENDER, renderHandler);
     }

     // number of milliseconds we think it takes to render the screen
     public var RENDER_DEDUCTION:int = 10;

     private var fn:Function;
     private var obj:Object;
     private var thread:UIComponent;
     private var start:Number;
     private var due:Number;

     private var mouseEvent:Boolean;
     private var keyEvent:Boolean;

     private function enterFrameHandler(event:Event):void
     {
        start = getTimer();
        var fr:Number = Math.floor(1000 / thread.systemManager.stage.frameRate);
        due = start + fr;

        thread.systemManager.stage.invalidate();
        thread.graphics.clear();
        thread.graphics.moveTo(0, 0);
        thread.graphics.lineTo(0, 0);   
     }

     private function renderHandler(event:Event):void
     {
         if (mouseEvent || keyEvent)
             due -= RENDER_DEDUCTION;

         while (getTimer() < due)
         {
            if (!fn(obj))
            {
                if (!thread.parent)
                    return;

                var sm:ISystemManager = thread.systemManager;
                sm.stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
                sm.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                sm.stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
                sm.removeChild(thread);
                thread.removeEventListener(Event.RENDER, renderHandler);
                dispatchEvent(new Event("threadComplete"));
            }
         }

         mouseEvent = false;
         keyEvent = false;
     }

     private function mouseMoveHandler(event:Event):void
     {
        mouseEvent = true;
     }

     private function keyDownHandler(event:Event):void
     {
        keyEvent = true;
     }
 } 
}

Это позволит вам выполнить процесс без заморозки пользовательского интерфейса. Он в основном использует событие этапа RENDER для отсрочки обработки. Этот код выполняет как можно больше вычислений ActionScript, ограниченных временем, необходимым для поддержания частоты кадров. Для получения дополнительной информации см .: http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html

...