【问题标题】:Flash UI blocked during flex rpc.soap.Operation::sendFlash UI 在 flex rpc.soap.Operation::send 期间被阻止
【发布时间】:2010-02-18 21:45:53
【问题描述】:

我有一个 Flash UI,它会定期调用服务器以获取一些更新的信息。该调用使用 flex sdk 的 rpc.soap.Operation 类。它看起来像这样:

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

此调用从 SQL 数据库中获取一些数据。我已经将调用从发送之前到 wsResult 函数开始的时间设置为约 4 秒。在此期间,我的 UI 没有更新。它被冻结/无响应。

现在,我知道 Flash 是单线程/异步的,所以我不确定为什么会这样。我看到 send(..) 函数返回一个我没有使用的 AsyncToken。这可能与它有关吗?

感谢任何其他关于为什么会发生这种情况的想法。谢谢。


我仍然没有找到可接受的解决方案。在 4 秒的通话期间,我必须使用伪线程来获取 flash 以更新 UI,这似乎很荒谬。我想知道肥皂响应的解析是否会占用大量时间。如果有很多处理要做,Flash会无限延迟更新UI吗?

【问题讨论】:

    标签: apache-flex flash actionscript-3 soap rpc


    【解决方案1】:

    您将在 Flash 中冻结 UI,因为它是单线程的。但是,您可以使用以下方式执行伪线程:

    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;
         }
     } 
    }
    

    这将使您能够在没有 UI 冻结的情况下执行流程。它基本上使用舞台的 RENDER 事件来延迟处理。此代码执行尽可能多的 Actionscript 计算,但受限于维持帧速率所需的时间。更多信息请见:http://blogs.adobe.com/aharui/2008/01/threads_in_actionscript_3.html

    【讨论】:

    • 感谢您的想法。我要调查一下。但是,由于它是异步的,不应该 flash 发送请求,然后返回处理 UI 内容,直到它被返回的数据中断?为什么需要做这个伪线程?
    • 它模拟了同时工作的两个进程。发送请求然后处理 UI 是您现在冻结的问题。使用我给你的类似的东西将消除几乎所有情况下的屏幕冻结 - 为你的用户提供更好的体验。
    • 考虑到他正在处理已经异步的东西,我看不出这如何解决问题。可能只是玩家使用中的一个错误。或者也许发送的调用根本不是问题,你确定它挂在哪里?
    • 它是常见 Flash 问题的常见解决方案。虽然可能有其他原因,但通常的原因是一个需要很长时间才能完成的过程,这会冻结 UI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多