工作人员在 运行 状态后未收到消息,但稍后会收到
Worker not receiving messages after RUNNING state, but it does later
更新: 显然,这是某种时间问题。在下面的代码中,我从点击处理程序创建工作人员,但如果我从 Main 构造函数创建工作人员(如文档示例所做的那样),commandChannel
消息会到达工作人员——即使在任何一种情况下我我正在做完全相同的事情:创建工作人员,监听 RUNNING
状态,然后通过 commandChannel
发送消息。但是,只有当我从 Main 构造函数创建 worker 时,第一条消息才会通过,而稍后的消息(一些未确定的时间在 RUNNING
之后)总是会通过。为什么? 如果我不能依靠 WorkerState.RUNNING
知道什么时候可以向工作人员发送消息,我怎么知道工作人员何时准备好接收消息?
我基本上拥有与 documentation example 完全相同的东西,但它不起作用。我的设置是:
- Flash Pro CC
- 桌面版 AIR 17
- Windows 7
问题是 worker 似乎没有通过传入消息通道接收消息,尽管它可以通过传出消息通道成功地将消息发送到主 SWF。
这是我的主class:
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 class:
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,因此它是特定于主到工作消息通道的东西。怎么了?
此外,似乎 trace
工作程序的操作或运行时错误都没有被主 SWF 捕获。如何调试 worker SWF?
This seems to be a known issue (see point 2)。 WorkerState.RUNNING
有时 在 worker 的构造函数实际 运行 之前被分派。因此,在我的例子中,在 worker 的构造函数添加侦听器以接收它之前,从点击处理程序发送了第一条消息。
所以我将采用简单的解决方法:当工作程序加载时,向主线程发送一条消息,在构造函数的末尾显示 "I'm ready"。在主线程中,在发送初始命令之前监听它而不是 RUNNING
。
更新: 显然,这是某种时间问题。在下面的代码中,我从点击处理程序创建工作人员,但如果我从 Main 构造函数创建工作人员(如文档示例所做的那样),commandChannel
消息会到达工作人员——即使在任何一种情况下我我正在做完全相同的事情:创建工作人员,监听 RUNNING
状态,然后通过 commandChannel
发送消息。但是,只有当我从 Main 构造函数创建 worker 时,第一条消息才会通过,而稍后的消息(一些未确定的时间在 RUNNING
之后)总是会通过。为什么? 如果我不能依靠 WorkerState.RUNNING
知道什么时候可以向工作人员发送消息,我怎么知道工作人员何时准备好接收消息?
我基本上拥有与 documentation example 完全相同的东西,但它不起作用。我的设置是:
- Flash Pro CC
- 桌面版 AIR 17
- Windows 7
问题是 worker 似乎没有通过传入消息通道接收消息,尽管它可以通过传出消息通道成功地将消息发送到主 SWF。
这是我的主class:
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 class:
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,因此它是特定于主到工作消息通道的东西。怎么了?
此外,似乎 trace
工作程序的操作或运行时错误都没有被主 SWF 捕获。如何调试 worker SWF?
This seems to be a known issue (see point 2)。 WorkerState.RUNNING
有时 在 worker 的构造函数实际 运行 之前被分派。因此,在我的例子中,在 worker 的构造函数添加侦听器以接收它之前,从点击处理程序发送了第一条消息。
所以我将采用简单的解决方法:当工作程序加载时,向主线程发送一条消息,在构造函数的末尾显示 "I'm ready"。在主线程中,在发送初始命令之前监听它而不是 RUNNING
。