Today I tried to do some background work with the AS3 Worker class.
However, I am experiencing weird behavior when developping my AIR desktop application in Flash CC on Windows 7. Consider this simple file for the main "thread":
////////////////
// MainThread.as
////////////////
package{
import flash.display.*;
import flash.system.*;
import flash.events.*;
import flash.utils.*;
public class MainThread extends MovieClip
{
[Embed(source="WorkerThread.swf", mimeType="application/octet-stream")]
private static var WORKER_SWF:Class;
var mainToWorker:MessageChannel;
var workerToMain:MessageChannel;
var workerToMainStartup:MessageChannel;
public function MainThread()
{
var workerBytes:ByteArray = new WORKER_SWF() as ByteArray;
var worker:Worker = WorkerDomain.current.createWorker(workerBytes, true);
// Send to worker
mainToWorker = Worker.current.createMessageChannel(worker);
worker.setSharedProperty("mainToWorker", mainToWorker);
// Receive from worker
workerToMain = worker.createMessageChannel(Worker.current);
workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMain);
worker.setSharedProperty("workerToMain", workerToMain);
// Receive startup message from worker
workerToMainStartup = worker.createMessageChannel(Worker.current);
workerToMainStartup.addEventListener(Event.CHANNEL_MESSAGE, onWorkerToMainStartup);
worker.setSharedProperty("workerToMainStartup", workerToMainStartup);
worker.start();
trace("hi");
}
private function onWorkerToMain(ev:Event): void
{
}
private function onWorkerToMainStartup(ev:Event): void
{
var success:Boolean = workerToMainStartup.receive() as Boolean;
trace(success);
if (!success)
{
// ... handle worker startup failure case
}
}
}
}
And then this file for the worker (the swf of this file is built in FlashDevelop):
//////////////////
// WorkerThread.as
//////////////////
package{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.system.*;
import flash.events.*;
import flash.filesystem.*;
public class WorkerThread extends MovieClip
{
public var mainToWorker:MessageChannel;
public var workerToMain:MessageChannel;
public var workerToMainStartup:MessageChannel;
public function WorkerThread()
{
// Receive from main
mainToWorker = Worker.current.getSharedProperty("mainToWorker");
mainToWorker.addEventListener(Event.CHANNEL_MESSAGE, onMainToWorker);
// Send to main
workerToMain = Worker.current.getSharedProperty("workerToMain");
// Send startup message to main
workerToMainStartup = Worker.current.getSharedProperty("workerToMainStartup");
workerToMainStartup.send(true);
trace("Hello from worker world.");
var file:File = File.desktopDirectory.resolvePath("MyTextFile.txt");
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.writeUTFBytes("ZA WARUDO.");
stream.close();
}
private function onMainToWorker(event:Event): void
{
}
}
}
Here are the problems I'm experiencing when building and launching the application from Flash CC:
- Traces from worker world can't be seen in the Flash CC debugger.
- The onWorkerToMainStartup listener is never fired, despite the worker running (tracing
worker.state
after a brief delay will confirm that). - The worker is supposed to write a file but that never happens.
However...
- The worker will write the file once I stop the debugger in Flash CC.
- After publishing the app and executing it from Windows Explorer, it works as it should (meaning, the file is written in the background, while the application runs, as expected).
This is crazy. Why does this happen?
Thanks.