ActionScript Workers: Changing ByteArray Length
In the last article we learned that a ByteArray
shared between two workers also shares its length
field but not its position
field. This raises a followup question: what about when the length changes? Today’s article sees what happens when you change the length of a ByteArray
that is shared between two ActionScript workers to see just how shared that length
field really is.
To recap, here’s how you set up a shared ByteArray
:
// Main thread bytes.shareable = true; worker.setSharedProperty("bytes", bytes); // Worker thread var bytes:ByteArray = Worker.current.getSharedProperty("bytes");
Setting shareable
to true
stops the ByteArray
from being copied to the other worker. Instead, the other worker receives the “same” ByteArray
. However, as we found out in the last article, this is not true: the position
field is different in each worker. Instead, there are two ByteArray
objects that share the same bytes.
Now to test just how well these two ByteArray
objects are kept in sync with each other. What happens when you set the length
in one worker? Does the other worker see the length
change or is the length only set when the worker receives a shared ByteArray
? How about when you call ByteArray.clear? Does that reset the other worker’s ByteArray
to have a length of zero? The following app tests both of these scenarios:
package { import flash.display.Sprite; import flash.events.Event; import flash.utils.ByteArray; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; public class ByteArrayTest extends Sprite { private var logger:TextField = new TextField(); private function log(msg:String): void { logger.appendText(msg+"\n"); } private var bytes:ByteArray = new ByteArray(); private var workerToMain:MessageChannel; private var mainToWorker:MessageChannel; private var worker:Worker; public function ByteArrayTest() { logger.autoSize = TextFieldAutoSize.LEFT; addChild(logger); if (Worker.current.isPrimordial) { startMainThread(); } else { startWorkerThread(); } } private function startMainThread(): void { bytes = new ByteArray(); bytes.length = 20; bytes.shareable = true; log("Main thread created ByteArray with length: " + bytes.length); worker = WorkerDomain.current.createWorker(this.loaderInfo.bytes); workerToMain = worker.createMessageChannel(Worker.current); workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWTM1); mainToWorker = Worker.current.createMessageChannel(worker); worker.setSharedProperty("mainToWorker", mainToWorker); worker.setSharedProperty("workerToMain", workerToMain); worker.setSharedProperty("bytes", bytes); worker.start(); } private function startWorkerThread(): void { workerToMain = Worker.current.getSharedProperty("workerToMain"); mainToWorker = Worker.current.getSharedProperty("mainToWorker"); mainToWorker.addEventListener(Event.CHANNEL_MESSAGE, onMainToWorker); bytes = Worker.current.getSharedProperty("bytes"); workerToMain.send("Worker thread starting up. Sees ByteArray length: " + bytes.length); } private function onWTM1(ev:Event): void { workerToMain.removeEventListener(Event.CHANNEL_MESSAGE, onWTM1); workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWTM2); log((ev.target as MessageChannel).receive()); log("Main thread setting length to 40"); bytes.length = 40; mainToWorker.send(true); } private function onWTM2(ev:Event): void { workerToMain.removeEventListener(Event.CHANNEL_MESSAGE, onWTM2); workerToMain.addEventListener(Event.CHANNEL_MESSAGE, onWTM3); log((ev.target as MessageChannel).receive()); log("Main thread calling clear()"); bytes.clear(); mainToWorker.send(true); } private function onWTM3(ev:Event): void { log((ev.target as MessageChannel).receive()); } private function onMainToWorker(ev:Event): void { workerToMain.send("Worker thread received message. Sees ByteArray length: " + bytes.length); } } }
Here’s what the app prints out:
Main thread created ByteArray with length: 20 Worker thread starting up. Sees ByteArray length: 20 Main thread setting length to 40 Worker thread received message. Sees ByteArray length: 40 Main thread calling clear() Worker thread received message. Sees ByteArray length: 0
As you can see, the length
property seems to be kept in sync throughout both the set length
and clear
calls. Each time the worker thread sees the length property updated appropriately. Since communication between workers can be awkward, slow, or both, it’s a good thing that length
is effectively shared between them automatically. The lack of sharing position
, however, seems to be a point of debate.
Spot a bug? Have a suggestion or a question? Post a comment!