Paket | flash.system |
Klasse | public final class Worker |
Vererbung | Worker EventDispatcher Object |
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Ein Worker ermöglicht Ihnen, Code im Hintergrund auszuführen, während gleichzeitig in einem anderen Worker (auch im Worker der Haupt-SWF-Datei) andere Operationen ausgeführt werden. Wenn keine Worker verwendet werden, kann zum Beispiel das Verarbeiten großer Datenmengen in einer Schleife so lange dauern, dass der Hauptanwendungsthread den Bildschirm nicht schnell genug aktualisieren kann. Dies kann zu stockenden Bildern oder dem Einfrieren der Anzeige führen.
Mithilfe eines Workers können Sie lang dauernde oder langsame Operationen im Hintergrund ausführen. Jeder Worker führt seinen Code in einem separaten Ausführungsthread aus. Code mit einer langen Ausführungsdauer in einem Worker verhindert nicht, dass Code in einem anderen Worker ausgeführt werden kann. Die beiden Codesets werden vielmehr gleichzeitig (parallel) ausgeführt. Deshalb kann ein Worker verwendet werden, um Code im Hintergrund auszuführen, während der Hauptanwendungsthread ungehindert den Bildschirm aktualisieren kann.
Diese Fähigkeit, mehrere Sätze von Codeanweisungen simultan auszuführen, wird Parallelität oder Gleichzeitigkeit genannt.
Hinweis: Die Verwendung von Workern für die Parallelität wird in Flash Player und in AIR auf Desktopplattformen unterstützt. Für mobile Plattformen wird Parallelität in AIR unter Android und iOS unterstützt. Mit der statischen Eigenschaft isSupported können Sie überprüfen, ob Parallelität unterstützt wird, bevor Sie versuchen, diese zu verwenden.
Sie erstellen Worker-Instanzen nicht direkt, indem Sie den Worker()
-Konstruktor aufrufen. Wenn die Verwendung von Workern für die Parallelität unterstützt wird, erstellt die Laufzeitumgebung beim Starten automatisch den Worker, der der Haupt-SWF-Datei zugeordnet ist und ursprünglicher Worker genannt wird.
Jeder weitere Worker wird aus einer separaten SWF-Datei erstellt. Um eine neue Instanz der Worker-Klasse zu erstellen, übergeben Sie ein ByteArray mit den Bytes der SWF-Datei des Hintergrundworkers als Argument an die createWorker()
-Methode der WorkerDomain-Klasse. Es gibt drei gebräuchliche Wege, um zu diesem Zweck auf die Bytes einer SWF-Datei zuzugreifen:
-
Verwenden Sie das [Embed]-Metatag, um die SWF-Datei als ByteArray in die Anwendung einzubetten:
// Embed the SWF file [Embed(source="../swfs/BgWorker.swf", mimeType="application/octet-stream")] private static var BgWorker_ByteClass:Class; private function createWorker():void { // create the background worker var workerBytes:ByteArray = new BgWorker_ByteClass(); var bgWorker:Worker = WorkerDomain.current.createWorker(workerBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); }
-
Laden Sie eine externe SWF-Datei unter Verwendung eines URLLoader:
// load the SWF file var workerLoader:URLLoader = new URLLoader(); workerLoader.dataFormat = URLLoaderDataFormat.BINARY; workerLoader.addEventListener(Event.COMPLETE, loadComplete); workerLoader.load(new URLRequest("BgWorker.swf")); private function loadComplete(event:Event):void { // create the background worker var workerBytes:ByteArray = event.target.data as ByteArray; var bgWorker:Worker = WorkerDomain.current.createWorker(workerBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); }
-
Verwenden Sie eine einzelne SWF-Datei sowohl als ursprünglichen Worker als auch als Hintergrundworker:
// The primordial worker's main class constructor public function PrimordialWorkerClass() { init(); } private function init():void { var swfBytes:ByteArray = this.loaderInfo.bytes; // Check to see if this is the primordial worker if (Worker.current.isPrimordial) { // create a background worker var bgWorker:Worker = WorkerDomain.current.createWorker(swfBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); } else // entry point for the background worker { // set up communication between workers using getSharedProperty() // ... (not shown) // start the background work } }
Worker werden isoliert voneinander ausgeführt und haben keinen Zugriff auf denselben Arbeitsspeicher, dieselben Variablen oder denselben Code. Es sind jedoch drei Mechanismen verfügbar, um Nachrichten und Daten zwischen Worker-Instanzen zu übergeben:
- Gemeinsame Eigenschaften: Jeder Worker verfügt über einen internen Satz benannter Variablen, die sowohl im Worker selbst als auch von anderen Workern festgelegt und gelesen werden können. Sie können einen Wert mit der
setSharedProperty()
-Methode festlegen und mit dergetSharedProperty()
-Methode abrufen. - MessageChannel: Mithilfe eines MessageChannel-Objekts können Sie Nachrichten und Daten von einem Worker zu einem anderen senden (nur in einer Richtung). Code im empfangenden Worker kann einen Listener für ein Ereignis verwenden, um beim Eingehen einer Nachricht benachrichtigt zu werden. Um ein MessageChannel-Objekt zu erstellen, verwenden Sie die
createMessageChannel()
-Methode. - Gemeinsam nutzbares ByteArray: Wenn die
shareable
-Eigenschaft eines ByteArray-Objekts den Werttrue
hat, wird der gleiche zugrunde liegende Speicher für Instanzen dieses ByteArray-Objekts in allen Workern verwendet. Da der Code in mehreren Workern gleichzeitig auf den gemeinsamen Speicher zugreifen kann, muss Ihr Code die Mechanismen verwenden, die für dieByteArray.shareable
-Eigenschaft beschrieben werden, um Probleme mit unerwarteten Datenänderungen zu vermeiden.
Verschiedene Laufzeit-APIs sind in Code, der in einem Hintergrundworker ausgeführt wird, nicht verfügbar. Dies sind hauptsächlich APIs, die mit der Benutzereingabe und Ausgabemechanismen zu tun haben, oder Betriebssystemelemente wie Fenster und Ziehen. Für eine API, die nicht in allen Kontexten unterstützt wird, sollten Sie isSupported
, available
und ähnliche Eigenschaften verwenden, um zu überprüfen, ob die API im Hintergrundworkerkontext verfügbar ist, bevor Sie versuchen, die API zu verwenden.
Hinweis: Native Erweiterungen werden nicht für Hintergrund und sekundäre Mitarbeiter unterstützt.
Worker sind hilfreich, da sie die Wahrscheinlichkeit verringern, dass die Framerate aufgrund der Blockierung des Hauptrenderingthreads durch anderen Code abfällt. Auf der anderen Seite erfordern Worker zusätzlichen Systemarbeitsspeicher und CPU-Rechenleistung, was die allgemeine Anwendungsleistung verringern kann. Da jeder Worker seine eigene Instanz der virtuellen Maschine der Laufzeitumgebung verwendet, kann der Mehraufwand auch bei trivialen Workern erheblich ins Gewicht fallen. Wenn Sie Worker verwenden, testen Sie Ihren Code auf allen Zielplattformen, um sicherzustellen, dass die Anforderungen an das System nicht zu groß sind. Adobe empfiehlt, in einem typischen Szenario nicht mehr als ein oder zwei Hintergrundworker zu verwenden.
Weitere Informationen
Intro to AS3 Workers: Image Processing von Shawn Blais
Multithreaded Physics: Using AS3 Workers for a physics engine von Shawn Blais
Verwandte API-Elemente
Eigenschaft | Definiert von | ||
---|---|---|---|
constructor : Object
Ein Verweis auf das Klassenobjekt oder die Konstruktorfunktion für eine angegebene Objektinstanz. | Object | ||
current : Worker [statisch] [schreibgeschützt]
Ermöglicht den Zugriff auf den Worker, der den aktuellen Code enthält
| Worker | ||
isPrimordial : Boolean [schreibgeschützt]
Gibt an, ob dieser Worker der ursprüngliche Worker ist. | Worker | ||
isSupported : Boolean [statisch] [schreibgeschützt]
Gibt an, ob die aktuelle Laufzeitumgebung die Verwendung von Worker-Objekten für die gleichzeitige Codeausführung (Parallelität) unterstützt. | Worker | ||
state : String [schreibgeschützt]
Der aktuelle Zustand des Workers in seinem Lebenszyklus. | Worker |
Methode | Definiert von | ||
---|---|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void [override]
Registriert ein Ereignis-Listener-Objekt bei einem EventDispatcher-Objekt, sodass der Listener über ein Ereignis benachrichtigt wird. | Worker | ||
Erstellt eine neue MessageChannel-Instanz, um Nachrichten von dem Worker, bei dem die Methode aufgerufen wurde, an einen anderen (empfangenden) Worker zu senden. | Worker | ||
Sendet ein Ereignis in den Ereignisablauf. | EventDispatcher | ||
Ruft einen Wert ab, der mit einem benannten Schlüssel in diesem Worker gespeichert ist. | Worker | ||
Überprüft, ob das EventDispatcher-Objekt Listener für einen bestimmten Ereignistyp registriert hat. | EventDispatcher | ||
Gibt an, ob für ein Objekt eine bestimmte Eigenschaft definiert wurde. | Object | ||
Gibt an, ob eine Instanz der Object-Klasse in der Prototypkette des Objekts vorhanden ist, das als Parameter angegeben wurde. | Object | ||
Gibt an, ob die angegebene Eigenschaft vorhanden ist und durchlaufen werden kann. | Object | ||
[override]
Entfernt einen Listener aus dem EventDispatcher-Objekt. | Worker | ||
Legt die Verfügbarkeit einer dynamischen Eigenschaft für Schleifenoperationen fest. | Object | ||
Stellt einen benannten Wert bereit, der für Code verfügbar ist, der in der SWF-Datei des Workers ausgeführt wird. | Worker | ||
Beginnt mit der Ausführung des Workers. | Worker | ||
Beendet die Ausführung des Workercodes. | Worker | ||
Gibt die Stringdarstellung dieses Objekts zurück, formatiert entsprechend den Konventionen des Gebietsschemas. | Object | ||
Gibt das angegebene Objekt als String zurück. | Object | ||
Gibt den Grundwert des angegebenen Objekts zurück. | Object | ||
Überprüft, ob bei diesem EventDispatcher-Objekt oder bei einem seiner Vorgänger ein Ereignis-Listener für einen bestimmten Ereignistyp registriert ist. | EventDispatcher |
Ereignis | Übersicht | Definiert von | ||
---|---|---|---|---|
[broadcast event] Wird ausgelöst, wenn Flash Player oder eine AIR-Anwendung den Betriebssystemfokus erhält und aktiv wird. | EventDispatcher | |||
[broadcast event] Wird ausgelöst, wenn Flash Player- oder die AIR-Anwendung den Fokus verliert und inaktiv wird. | EventDispatcher | |||
Wird abgesetzt, wenn sich der Wert der state-Eigenschaft des Workers ändert. | Worker |
current | Eigenschaft |
isPrimordial | Eigenschaft |
isPrimordial:Boolean
[schreibgeschützt] Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Gibt an, ob dieser Worker der ursprüngliche Worker ist.
Der ursprüngliche Worker ist der Worker, in dem die erste SWF-Datei ausgeführt wird. Dieser Worker steuert das Rendern des Bildschirms.
Diese Eigenschaft kann verwendet werden, um eine Anwendung zu entwerfen, in der der ursprüngliche Worker und der Hintergrundworker zwei Instanzen derselben SWF-Datei sind. Alternativ dazu können Sie Ihren Code auch so aufbauen, dass der Hintergrundworker anderen Code verwendet, der in eine andere SWF-Datei des ursprünglichen Workers kompiliert wird.
Implementierung
public function get isPrimordial():Boolean
isSupported | Eigenschaft |
isSupported:Boolean
[schreibgeschützt] Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Gibt an, ob die aktuelle Laufzeitumgebung die Verwendung von Worker-Objekten für die gleichzeitige Codeausführung (Parallelität) unterstützt.
Wenn Parallelität unterstützt wird, hat diese Eigenschaft den Wert true
.
Implementierung
public static function get isSupported():Boolean
state | Eigenschaft |
state:String
[schreibgeschützt] Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Der aktuelle Zustand des Workers in seinem Lebenszyklus. Die möglichen Werte für diese Eigenschaft werden in der WorkerState-Klasse definiert.
Implementierung
public function get state():String
Verwandte API-Elemente
addEventListener | () | Methode |
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Registriert ein Ereignis-Listener-Objekt bei einem EventDispatcher-Objekt, sodass der Listener über ein Ereignis benachrichtigt wird. Sie können Ereignis-Listener bei allen Knoten in der Anzeigeliste für eine bestimmte Art von Ereignis, Phase oder Priorität registrieren.
Nachdem Sie einen Ereignis-Listener erfolgreich registriert haben, können Sie seine Priorität nicht durch weitere Aufrufe von addEventListener()
ändern. Um die Priorität eines Listeners zu ändern, müssen Sie zunächst removeListener()
aufrufen. Anschließend können Sie den Listener mit der neuen Prioritätsstufe erneut aufrufen.
Nach der Registrierung des Listeners haben nachfolgende Aufrufe von addEventListener()
mit einem anderen type
- oder useCapture
-Wert eine separate Listener-Registrierung zur Folge. Wenn Sie beispielsweise zuerst einen Listener registrieren, für den useCapture
auf true
gesetzt ist, wird dieser nur während der Aufnahmephase aktiv sein. Wenn Sie addEventListener()
für dasselbe Listener-Objekt erneut aufrufen, diesmal aber useCapture
auf false
gesetzt ist, werden zwei separate Listener angelegt: einer, der während der Aufnahmephase aktiv ist und ein zweiter, der während der Ziel- und Bubbling-Phase aktiv ist.
Sie können einen Ereignis-Listener nicht nur für die Ziel- oder Bubbling-Phase registrieren. Die beiden Phasen hängen während der Registrierung immer zusammen, da Bubbling nur für übergeordnete Elemente des Zielknotens gilt.
Wenn Sie einen Ereignis-Listener nicht mehr brauchen, entfernen sie ihn, indem Sie removeEventListener()
aufrufen. Andernfalls könnte es zu Speicherproblemen kommen. Ereignis-Listener werden nicht automatisch aus dem Speicher entfernt, da der Garbage Collector den Listener nicht entfernt, solange das auslösende Objekt vorhanden ist (sofern der useWeakReference
-Parameter auf true
gesetzt ist).
Beim Kopieren einer EventDispatcher-Instanz werden zugewiesene Ereignis-Listener nicht kopiert. (Wenn ein neu angelegter Knoten einen Ereignis-Listener benötigt, müssen Sie den Listener nach dem Erstellen des Knotens zuweisen.) Wenn Sie jedoch eine EventDispatcher-Instanz verschieben, werden zugewiesene Ereignis-Listener ebenfalls verschoben.
Wenn der Ereignis-Listener bei einem Knoten registriert wird, während mit diesem Knoten ein Ereignis durchgeführt wird, so wird der Ereignis-Listener während der aktuellen Phase nicht ausgelöst, kann aber während einer späteren Phase im Ereignisablauf ausgelöst werden, etwa während der Bubbling-Phase.
Wird ein Ereignis-Listener von einem Knoten entfernt, während mit dem Knoten ein Ereignis durchgeführt wird, so wird er von den aktuellen Aktionen immer noch ausgelöst. Nachdem er entfernt worden ist, wird der Ereignis-Listener nicht wieder aufgerufen (es sei denn er wird für spätere Verarbeitungsvorgänge erneut aufgerufen).
Parameter
type:String — Der Ereignistyp.
| |
listener:Function — Die Listener-Funktion, die das Ereignis verarbeitet. Diese Funktion muss ein Ereignisobjekt als einzigen Parameter akzeptieren und darf keinen Wert zurückgeben, wie das nachfolgende Beispiel zeigt:
function(evt:Event):void Der Name der Funktion ist beliebig. | |
useCapture:Boolean (default = false ) —
Bestimmt, ob der Listener in der Erfassungsphase oder in der Ziel- und Bubbling-Phase arbeitet. Ist useCapture auf true gesetzt, so verarbeitet der Listener das Ereignis nur während der Erfassungsphase und nicht während der Ziel- oder Bubbling-Phase. Hat useCapture hingegen den Wert false , verarbeitet der Listener das Ereignis nur während der Ziel- oder Bubbling-Phase. Um auf das Ereignis in allen drei Phasen zu warten, rufen Sie addEventListener() zweimal auf; einmal ist useCapture auf true gesetzt, und beim zweiten Mal hat useCapture den Wert false .
| |
priority:int (default = 0 ) — Die Prioritätsstufe des Ereignis-Listeners. Die Priorität wird durch eine vorzeichenbehaftete 32-Bit-Ganzzahl zugewiesen. Je höher die Zahl, desto höher die Priorität. Alle Listener mit der Priorität n werden vor Listenern mit der Priorität n -1 verarbeitet. Wenn zwei oder mehr Listener die gleiche Priorität aufweisen, werden sie in der Reihenfolge verarbeitet, in der sie hinzugefügt wurden. Die Standardpriorität ist 0.
| |
useWeakReference:Boolean (default = false ) — Bestimmt, ob der Verweis auf den Listener stark oder schwach ist. Ein starker Verweis (der Standard) verhindert, dass der Listener von einem Garbage Collector entfernt wird. Ein schwacher Verweis hingegen nicht. Funktionen von Mitgliedern auf Klassenebene werden nicht vom Garbagekollektor entfernt. Daher können Sie |
createMessageChannel | () | Methode |
public function createMessageChannel(receiver:Worker):MessageChannel
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Erstellt eine neue MessageChannel-Instanz, um Nachrichten von dem Worker, bei dem die Methode aufgerufen wurde, an einen anderen (empfangenden) Worker zu senden. Code in dem Worker, der das MessageChannel-Objekt erstellt, kann es verwenden, um unidirektionale Nachrichten an das als receiver
-Argument angegebene Worker-Objekt zu senden.
Eine MessageChannel-Instanz kann zwar verwendet werden, um Nachrichten und Daten von einer Worker-Instanz an eine andere zu senden, es muss jedoch mindestens eine MessageChannel-Instanz als gemeinsam genutzte Eigenschaft an einen untergeordneten Worker übergeben werden, indem die setSharedProperty()
-Methode des Worker-Objekts aufgerufen wird.
outgoingChannel = Worker.current.createMessageChannel(bgWorker); incomingChannel = bgWorker.createMessageChannel(Worker.current); bgWorker.setSharedProperty("incoming", outgoingChannel); bgWorker.setSharedProperty("outgoing", incomingChannel); // listen for messages from the receiving MessageChannel // This event is triggered when the background sends a message to this worker incomingChannel.addEventListener(Event.CHANNEL_MESSAGE, incomingMessageHandler);
Parameter
receiver:Worker — Der Worker, der Nachrichten empfängt, die über den erstellen Nachrichtenkanal übertragen werden
|
MessageChannel — Das MessageChannel-Objekt, das bei diesem Vorgang erstellt wird
|
getSharedProperty | () | Methode |
public function getSharedProperty(key:String):*
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Ruft einen Wert ab, der mit einem benannten Schlüssel in diesem Worker gespeichert ist.
Code in einem untergeordneten Worker kann diese Methode aufrufen, um einen Wert abzurufen. Dies kann sogar schon im Konstruktor der SWF-Hauptklasse des Workers erfolgen.
Parameter
key:String — Der Name der abzurufenden gemeinsam genutzten Eigenschaft
|
* — Der Wert der gemeinsam genutzten Eigenschaft, der mit dem angegebenen Schlüssel gespeichert wurde, oder null , falls kein Wert für den angegebenen Schlüssel gespeichert wurde
|
removeEventListener | () | Methode |
override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Entfernt einen Listener aus dem EventDispatcher-Objekt. Wenn kein entsprechender Listener mit dem EventDispatcher-Objekt registriert ist, hat ein Aufruf dieser Methode keine Auswirkungen.
Parameter
type:String — Der Ereignistyp.
| |
listener:Function — Das zu entfernende Listener-Objekt.
| |
useCapture:Boolean (default = false ) —
Gibt an, ob der Listener für die Erfassungsphase oder die Ziel- und Bubbling-Phase registriert wurde. Wenn der Listener sowohl für die Aufnahme- als auch für die Bubbling-Phase registriert wurde, sind auch zwei Aufrufe von removeEventListener() erforderlich, um beide zu entfernen: ein Aufruf, bei dem useCapture auf true gesetzt ist, und einer, bei dem useCapture auf false gesetzt ist.
|
setSharedProperty | () | Methode |
public function setSharedProperty(key:String, value:*):void
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Stellt einen benannten Wert bereit, der für Code verfügbar ist, der in der SWF-Datei des Workers ausgeführt wird.
Sie können diese Methode aufrufen, bevor Sie die start()
-Methode des Workers aufrufen. In diesem Fall ist die gemeinsam genutzte Eigenschaft zur Konstruktionszeit für den Code in der SWF-Datei des Workers verfügbar.
Der Wert, der an den value
-Parameter übergeben wird, kann ein nahezu beliebiges Objekt sein. Abgesehen von den unten aufgeführten Ausnahmen, werden Objekte, die an den value
-Parameter übergeben werden, nicht als Verweis übergeben. Alle Änderungen, die nach dem setSharedProperty()
-Aufruf an einem Objekt in einem Worker vorgenommen werden, werden nicht an den anderen Worker übertragen. Das Objekt wird kopiert, indem es in das AMF3-Format serialisiert und im empfangenden Worker in ein neues Objekt deserialisiert wird. Aus diesem Grund können Objekte, die nicht im AMF3-Format serialisiert werden können, zum Beispiel Anzeigeobjekte, nicht an den value
-Parameter übergeben werden. Damit eine benutzerdefinierte Klasse korrekt übergeben werden kann, muss die Klassendefinition mit der flash.net.registerClassAlias()
-Funktion oder unter Verwendung von [RemoteClass]
-Metadaten registriert werden. Bei beiden Techniken muss derselbe Alias für die Klassenversionen beider Worker verwendet werden.
Es gibt fünf Objekttypen, die eine Ausnahme der Regel darstellen, dass Objekte nicht von Workern gemeinsam genutzt werden:
- Worker
- MessageChannel
- gemeinsam nutzbares ByteArray (ein ByteArray-Objekt, dessen
shareable
-Eigenschaft auftrue
eingestellt ist - Mutex
- Condition
Wenn Sie eine Instanz dieser Objekte an den value
-Parameter übergeben, hat jeder Worker einen Verweis auf dasselbe zugrunde liegende Objekt. Änderungen, die in einem Worker an einer Instanz vorgenommen werden, sind sofort auch in den anderen Workern verfügbar. Wenn Sie dieselbe Instanz dieser Objekte mehrmals mit setSharedProperty()
übergeben, erstellt die Laufzeitumgebung keine neue Kopie des Objekts im empfangenden Worker. Stattdessen wird derselbe Verweis erneut verwendet, sodass der Arbeitsspeicher weniger belastet wird.
Mit dem Aufruf dieser Methode mit null
oder undefined
für das value
-Argument wird jeder zuvor festgelegte Wert für das angegebene key
-Argument gelöscht. Wenn ein Wert auf diese Weise gelöscht wird, wird der Verweis darauf entfernt, sodass er speicherbereinigt werden kann.
Sie können einen beliebigen Stringwert im key-Argument verwenden. Diese gemeinsam genutzten Eigenschaften stehen jedem Code zur Verfügung, der Zugriff auf einen Worker hat. Um das versehentliche Überschreiben eines Werts zu vermeiden, könnten Sie ein Präfix oder Suffix bzw. einen ähnlichen Mechanismus verwenden, sodass Ihre Schlüsselnamen eindeutig sind.
Parameter
key:String — Der Name, unter dem die gemeinsam genutzte Eigenschaft gespeichert ist.
| |
value:* — Der Wert der gemeinsam genutzten Eigenschaft.
|
Verwandte API-Elemente
start | () | Methode |
public function start():void
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Beginnt mit der Ausführung des Workers. Die Laufzeitumgebung erstellt den Workerthread und ruft den Konstruktor der Hauptklasse der SWF-Datei des Workers auf.
Dieser Vorgang ist asynchron. Nachdem der Workerstart abgeschlossen ist, ändert der Worker seine state
-Eigenschaft zu WorkerState.RUNNING
und setzt ein workerState
-Ereignis ab.
terminate | () | Methode |
public function terminate():Boolean
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Beendet die Ausführung des Workercodes. Mit dem Aufruf dieser Methode wird sämtlicher aktueller ActionScript-Code in der SWF-Datei des Workers abgebrochen.
RückgabewerteBoolean — true , wenn Code im Worker ausgeführt und unterbrochen wurde, oder false , wenn der Worker nie gestartet wurde
|
workerState | Ereignis |
flash.events.Event
Eigenschaft Event.type =
flash.events.Event.WORKER_STATE
Sprachversion: | ActionScript 3.0 |
Laufzeitversionen: | Flash Player 11.4, AIR 3.4 |
Wird abgesetzt, wenn sich der Wert der state
-Eigenschaft des Workers ändert.
Event.WORKER_STATE
-Konstante definiert den Wert der type
-Eigenschaft eines workerState
-Ereignisobjekts.
Dieses Ereignis verfügt über die folgenden Eigenschaften:
Eigenschaft | Wert |
---|---|
bubbles | false |
cancelable | false . Es gibt kein Standardverhalten, das abgebrochen werden kann. |
currentTarget | Das Objekt, welches das Ereignisobjekt aktiv mit einem Ereignis-Listener verarbeitet. |
target | Das Objekt, das dieses Ereignis abgesetzt hat. |
Dieses Beispiel besteht aus drei ActionScript-Klassen: WorkerExample ist die Hauptklasse und der übergeordnete Worker. BackgroundWorker ist die Klasse, die die Arbeit im Hintergrund übernimmt. Sie wird als Hauptklasse der SWF-Datei des Hintergrundworkers kompiliert. CountResult ist eine benutzerdefinierte Klasse, die verwendet wird, um Daten zwischen den beiden Workern als ein einzelnes Objekt anstatt mehrerer Werte zu übergeben.
In diesem Beispiel zählt der Hintergrundworker in einer Schleife bis zu einer vom übergeordneten Worker festgelegten Zahl. Dabei sendet er Nachrichten über seinen Fortschritt an den übergeordneten Worker. Wenn die Zählung fertig ist, sendet der Hintergrundworker eine Nachricht an den übergeordneten Worker, um ihm mitzuteilen, dass er fertig ist und wie lange die Zählung gedauert hat.
Die WorkerExample-Klasse ist die Hauptklasse der SWF-Datei und somit die Hauptklasse des ursprünglichen Workers. In der initialize()
-Methode erstellt der Code das Hintergrundworkerobjekt unter Verwendung der Bytes aus der BackgroundWorker-Klasse, die mit einem [Embed]
-Tag eingebettet werden.
Nachdem der Hintergrundworker durch Aufrufen von WorkerDomain.createWorker()
erstellt wurde, richtet der Code die Kommunikation zwischen den Workern ein. Zunächst erstellt der Code einen Satz MessageChannel-Objekte. Diese werden an den Hintergrundworker übergeben, indem dessen setSharedProperty()
-Methode aufgerufen wird. Zum Schluss wird ein Listener für das workerState
-Ereignis des Hintergrundworkerobjekts registriert und der Worker wird durch den Aufruf seiner start()
-Methode gestartet.
Während der Hintergrundworker seine Arbeit ausführt, sendet er Nachrichten über seinen Fortschritt (und schließlich das Ergebnis) an den übergeordneten Worker. Der übergeordnete Worker verwendet diese Informationen, um die Statusanzeige und den Text zu aktualisieren.
package { import com.adobe.example.vo.CountResult; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.net.registerClassAlias; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; import flash.system.WorkerState; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.utils.ByteArray; public class WorkerExample extends Sprite { // ------- Embed the background worker swf as a ByteArray ------- [Embed(source="../workerswfs/BackgroundWorker.swf", mimeType="application/octet-stream")] private static var BackgroundWorker_ByteClass:Class; public static function get BackgroundWorker():ByteArray { return new BackgroundWorker_ByteClass(); } private var bgWorker:Worker; private var bgWorkerCommandChannel:MessageChannel; private var progressChannel:MessageChannel; private var resultChannel:MessageChannel; public function WorkerExample() { initialize(); } private function initialize():void { // create the user interface setupStage(); createStatusText(); createProgressBar(); // Register the alias so we can pass CountResult objects between workers registerClassAlias("com.adobe.test.vo.CountResult", CountResult); // Create the background worker bgWorker = WorkerDomain.current.createWorker(BackgroundWorker); // Set up the MessageChannels for communication between workers bgWorkerCommandChannel = Worker.current.createMessageChannel(bgWorker); bgWorker.setSharedProperty("incomingCommandChannel", bgWorkerCommandChannel); progressChannel = bgWorker.createMessageChannel(Worker.current); progressChannel.addEventListener(Event.CHANNEL_MESSAGE, handleProgressMessage) bgWorker.setSharedProperty("progressChannel", progressChannel); resultChannel = bgWorker.createMessageChannel(Worker.current); resultChannel.addEventListener(Event.CHANNEL_MESSAGE, handleResultMessage); bgWorker.setSharedProperty("resultChannel", resultChannel); // Start the worker bgWorker.addEventListener(Event.WORKER_STATE, handleBGWorkerStateChange); bgWorker.start(); } private function handleBGWorkerStateChange(event:Event):void { if (bgWorker.state == WorkerState.RUNNING) { _statusText.text = "Background worker started"; bgWorkerCommandChannel.send(["startCount", 100000000]); } } private function handleProgressMessage(event:Event):void { var percentComplete:Number = progressChannel.receive(); setPercentComplete(percentComplete); _statusText.text = Math.round(percentComplete).toString() + "% complete"; } private function handleResultMessage(event:Event):void { var result:CountResult = resultChannel.receive() as CountResult; setPercentComplete(100); _statusText.text = "Counted to " + result.countTarget + " in " + (Math.round(result.countDurationSeconds * 10) / 10) + " seconds"; } // ------- Create UI ------- private var _currentPercentComplete:int = 0; private var _needsValidation:Boolean = false; private var _statusText:TextField; private var _progressBarRect:Shape; private var _progressBar:Shape; private function setupStage():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.stageWidth = 800; stage.stageHeight = 600; stage.color = 0xffffff; } private function createStatusText():void { _statusText = new TextField(); _statusText.width = 400; _statusText.height = 25; _statusText.x = (stage.stageWidth - _statusText.width) / 2; _statusText.y = 150; var statusTextFormat:TextFormat = new TextFormat(); statusTextFormat.color = 0xeeeeee; statusTextFormat.font = "Verdana"; statusTextFormat.align = TextFormatAlign.CENTER; statusTextFormat.size = 16; _statusText.defaultTextFormat = statusTextFormat; _statusText.wordWrap = false; _statusText.opaqueBackground = 0x999999; _statusText.selectable = false; _statusText.text = "Initializing..."; addChild(_statusText); } private function createProgressBar():void { _progressBarRect = new Shape(); _progressBarRect.graphics.beginFill(0x000000, 0); _progressBarRect.graphics.lineStyle(2, 0x000000); _progressBarRect.graphics.drawRect(0, 0, 400, 30); _progressBarRect.graphics.endFill(); _progressBarRect.x = (stage.stageWidth - _progressBarRect.width) / 2; _progressBarRect.y = 100; addChild(_progressBarRect); _progressBar = new Shape(); _progressBar.graphics.beginFill(0x0000ee); _progressBar.graphics.drawRect(0, 0, 391, 21); _progressBar.x = _progressBarRect.x + 4; _progressBar.y = _progressBarRect.y + 4; addChild(_progressBar); _progressBar.scaleX = 0; } private function setPercentComplete(percentComplete:int):void { if (_currentPercentComplete == percentComplete) return; _currentPercentComplete = percentComplete; invalidateValue(); } private function invalidateValue():void { if (_needsValidation) return; _needsValidation = true; addEventListener(Event.EXIT_FRAME, validate); } private function validate(event:Event):void { removeEventListener(Event.EXIT_FRAME, validate); _needsValidation = false; _redrawProgressBar(); } private function _redrawProgressBar():void { _progressBar.scaleX = _currentPercentComplete / 100; } } }
In der initialize()
-Methode empfängt sie die MessageChannel-Objekte, die der übergeordnete Worker übergeben hat. Diese werden für die Kommunikation zwischen den beiden Workern verwendet.
Der übergeordnete Worker ruft die send()
-Methode für den commandChannel
-Nachrichtenkanal auf, um eine Nachricht zu senden. Innerhalb des Hintergrundworkers setzt die Laufzeitumgebung dann das channelMessage
-Ereignis ab, indem die handleCommandMessage()
-Methode aufgerufen wird.
Die eigentliche Arbeit des Hintergrundworkers findet in der count()
-Methode statt. Während der Hintergrundworker mit seiner Zählung fortfährt, sendet er Fortschrittsmeldungen an den übergeordneten Worker, indem er die send()
-Methode des MessageChannel-Objekts progressChannel
aufruft. Wenn die Zählung beendet ist, ruft er die send()
-Methode des MessageChannel-Objekts resultChannel
auf.
package com.adobe.example.workers { import com.adobe.example.vo.CountResult; import flash.display.Sprite; import flash.events.Event; import flash.net.registerClassAlias; import flash.system.MessageChannel; import flash.system.Worker; import flash.utils.getTimer; public class BackgroundWorker extends Sprite { private var commandChannel:MessageChannel; private var progressChannel:MessageChannel; private var resultChannel:MessageChannel; public function BackgroundWorker() { initialize(); } private function initialize():void { registerClassAlias("com.adobe.test.vo.CountResult", CountResult); // Get the MessageChannel objects to use for communicating between workers // This one is for receiving messages from the parent worker commandChannel = Worker.current.getSharedProperty("incomingCommandChannel") as MessageChannel; commandChannel.addEventListener(Event.CHANNEL_MESSAGE, handleCommandMessage); // These are for sending messages to the parent worker progressChannel = Worker.current.getSharedProperty("progressChannel") as MessageChannel; resultChannel = Worker.current.getSharedProperty("resultChannel") as MessageChannel; } private function handleCommandMessage(event:Event):void { if (!commandChannel.messageAvailable) return; var message:Array = commandChannel.receive() as Array; if (message != null && message[0] == "startCount") { count(uint(message[1])); } } private function count(targetValue:uint):void { var startTime:int = getTimer(); var onePercent:uint = uint(Math.ceil(targetValue / 100)); var oneHalfPercent:Number = onePercent / 2; var i:uint = 0; while (i < targetValue) { i++; // only send progress messages every one-half-percent milestone // to avoid flooding the message channel if (i % oneHalfPercent == 0) { progressChannel.send(i / onePercent); } } var elapsedTime:int = getTimer() - startTime; var result:CountResult = new CountResult(targetValue, elapsedTime / 1000); resultChannel.send(result); trace("counted to", targetValue.toString(), "in", elapsedTime, "milliseconds"); } } }
registerClassAlias()
-Methode unter Verwendung desselben Aliasnamens auf.
package com.adobe.example.vo { public class CountResult { public function CountResult(countTarget:uint=0, countTime:Number=0) { this.countTarget = countTarget; this.countDurationSeconds = countTime; } public var countTarget:uint; public var countDurationSeconds:Number; } }
1. Wenn das dynamische Laden einer Remote-SWF-Datei mitActionScript-Code nicht funktioniert, muss die Remote-SWF-Datei an den Worker als eine eingeschränkte SWF-Datei übergeben werden. 2. Die Einbettung von SWF-Dateien (mit ABC-Code) mit [Embed]-Tag funktioniert nicht auf iOS. Jeder weitere Worker wird aus einer separaten SWF-Datei erstellt. Um eine neue Instanz der Worker-Klasse zu erstellen, übergeben Sie ein ByteArray mit den Bytes der SWF-Datei des Hintergrundworkers als Argument an die createWorker()
-Methode der WorkerDomain-Klasse.
Es gibt zwei übliche Möglichkeiten, um auf die Bytes einer SWF-Datei zu diesem Zweck auf iOS zuzugreifen: Die erste Möglichkeit verwendet Loader
, um eine externe SWF-Datei zu laden, und die zweite Möglichkeit verwendet URLLoader
, um die SWF-Datei zu laden.
Im folgenden Beispiel wird die Loader
-API, um die SWF-Datei zu laden.
package { import flash.display.Loader; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; import flash.text.TextField; import flash.text.TextFormat; public class IOSWorkerExample extends Sprite { public var worker:Worker; public var bm:MessageChannel; public var mb:MessageChannel; public var tf:TextField; public var tfrmt:TextFormat; public function IOSWorkerExample() { super(); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; tf=new TextField(); tfrmt= new TextFormat() tfrmt.size=80; tf.textColor = 0xFFFFF; tf.defaultTextFormat=tfrmt; addChild(tf); //creating the urlRequest object that references the background worker. var _urlRequest:URLRequest = new URLRequest("IOSBackWorker.swf"); var _loader:Loader = new Loader(); var _lc:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); _loader.load(_urlRequest, _lc); } // This function is called once the swf loading is completed public function completeHandler(e:Event):void { worker = WorkerDomain.current.createWorker(e.target.bytes); bm = worker.createMessageChannel(Worker.current); mb = Worker.current.createMessageChannel(worker); worker.setSharedProperty("btm", bm); worker.setSharedProperty("mtb", mb); //adding event handler on message receive from background bm.addEventListener(Event.CHANNEL_MESSAGE, onBackToMain); worker.start(); bm.receive(true); } public function errorHandler(e:IOErrorEvent):void { trace("In IO ErrorEvent Handler "+e.text); } //This function is called when the main thread receives the message from the background worker. public function onBackToMain(event:Event):void { if(bm.messageAvailable) { // displaying the percentages based on the message received from the background. var progress:Number = bm.receive(); trace("progress "+progress); tf.text= progress.toString(); } } } }
Loader
aufgerufen wird, muss die Überprüfung der isPrimordial
-Eigenschaft in den Hintergrund-Worker verschoben werden, wie in diesem Beispiel gezeigt.
package { import flash.display.Sprite; import flash.system.MessageChannel; import flash.system.Worker; import flash.utils.ByteArray; import flash.utils.getTimer; public class IOSBackWorker extends Sprite { private var memory:ByteArray = new ByteArray(); private var bm:MessageChannel; private var mb:MessageChannel; public function IOSBackWorker() { if(!Worker.current.isPrimordial) { memory.shareable = true; // creating objects of message channels bm = Worker.current.getSharedProperty("btm"); mb = Worker.current.getSharedProperty("mtb"); // calculating the percentage trace("message came"); var j:Number =1; while (j<1000) { for(var i=0;i<100;i++){} var startTime=getTimer(); // adding delay while (getTimer()-startTime <100); trace(j, (100*j)/1000); var progress:Number=(100*j)/1000; // sending the percentage to the main thread bm.send(progress); j++; } } } } }
Tue Jun 12 2018, 10:04 AM Z