工作人员在RUNNING状态后没有收到消息,但是稍后会这样做

时间:2015-09-02 08:59:02

标签: actionscript-3 air worker flash-cc

更新:显然,这是一种时间问题。在下面的代码中,我使用单击处理程序创建了worker,但是如果我从Main构造函数创建worker(正如doc示例所做的那样),commandChannel消息将传递给worker - 即使在任何一种情况下我都是我正在做同样的事情:创建工作人员,监听RUNNING状态,然后通过commandChannel发送消息。但是,如果我从Main构造函数创建工作程序,那么第一条消息才会通过,而稍后的消息(在RUNNING之后的某些未确定的时间)总是通过。为什么? 如果我不能依赖WorkerState.RUNNING知道何时可以向工作人员发送消息,我怎么知道工作人员何时准备接收消息?

我基本上与documentation example完全相同,但它不起作用。我的设置是:

  • Flash Pro CC
  • AIR 17 for Desktop
  • Windows 7

问题是工作人员似乎没有通过传入消息通道接收消息,尽管它可以通过传出消息通道成功地将消息发送到主SWF。

这是我的主要课程:

public class Main extends MovieClip {

    [Embed(source="TestWorker.swf", mimeType="application/octet-stream")]
    private var WorkerSWF:Class;
    private var workerBytes:ByteArray;

    private var worker:Worker;
    private var commandChannel:MessageChannel;
    private var resultChannel:MessageChannel;

    public function Main() {
        workerBytes = new WorkerSWF();
        stage.addEventListener(MouseEvent.CLICK, clickHandler);
    }

    private function clickHandler(e:MouseEvent):void {
        stage.removeEventListener(MouseEvent.CLICK, clickHandler);
        startWorker();
    }

    private function startWorker():void {
        trace("Start worker");

        worker = WorkerDomain.current.createWorker(workerBytes, true);

        commandChannel = Worker.current.createMessageChannel(worker);
        worker.setSharedProperty("commands", commandChannel);

        resultChannel = worker.createMessageChannel(Worker.current);
        resultChannel.addEventListener(Event.CHANNEL_MESSAGE, resultMessageHandler);
        worker.setSharedProperty("results", resultChannel);

        worker.addEventListener(Event.WORKER_STATE, workerStateHandler);
        worker.start();
    }

    private function workerStateHandler(e:Event):void {
        trace("Worker state:", worker.state);

        if(worker.state == WorkerState.RUNNING) {
            trace("Worker running");
            commandChannel.send("START PLEASE");
        }
    }

    private function resultMessageHandler(e:Event):void {
        trace(e, resultChannel.receive())
    }
}

我的工作人员SWF课程:

public class TestWorker extends Sprite {

    private var commandChannel:MessageChannel;
    private var resultChannel:MessageChannel;

    public function TestWorker () {
        trace("isPrimordial:", Worker.current.isPrimordial)

        commandChannel = Worker.current.getSharedProperty("commands") as MessageChannel;
        commandChannel.addEventListener(Event.CHANNEL_MESSAGE, commandMessageHandler);

        resultChannel = Worker.current.getSharedProperty("results") as MessageChannel;

        resultChannel.send("Hello from worker");
    }

    private function commandMessageHandler(e:Event):void {
        trace("commandMessageHandler")

        //var message:String = commandChannel.receive();

        resultChannel.send("Whatever.");

        setInterval(respond, 1000);
    }

    private function respond(){
        resultChannel.send("Whatever " + new Date());
    }

}

问题是工作人员commandMessageHandler从未被触发。我知道这是因为我从未收到回到主SWF的“Whatever”消息。 “Hello from worker”消息确实返回到主SWF,因此它是特定于main-to-worker消息通道的内容。怎么了?

此外,似乎主SWF没有捕获来自工作者的trace操作或运行时错误。如何调试工作者SWF?

1 个答案:

答案 0 :(得分:0)

This seems to be a known issue (see point 2)WorkerState.RUNNING 有时在工作者的构造函数实际运行之前被调度。所以在我的情况下,从click处理程序,在worker的构造函数添加了侦听器以接收它之前发送了第一条消息。

所以我将使用简单的解决方法:当工作程序加载时,在构造函数结束时向主线程发送一条消息,说明“我已经准备好了”。在主线程中,在发送初始命令之前,先听取RUNNING而不是IntentService