Pakket | flash.system |
Klasse | public final class Worker |
Overerving | Worker EventDispatcher Object |
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Met een worker kunt u code 'op de achtergrond' uitvoeren terwijl er op hetzelfde moment andere bewerkingen worden uitgevoerd in een andere worker (inclusief de SWF-hoofdworker). Bij systeemcontexten zonder workers neemt de uitvoering van sommige bewerkingen, zoals de verwerking van een grote gegevensset in een lus, zo veel tijd in beslag dat de schermweergave niet snel genoeg kan worden vernieuwd door de hoofdthread van de toepassing. Dit leidt tot een schokkerige weergave en soms zelfs tot het vastlopen van het scherm.
Met behulp van workers kunt u dergelijke langdurige of trage bewerkingen op de achtergrond uitvoeren. Elke worker voert zijn code uit in een afzonderlijke uitvoeringsthread, los van de andere workers. Hierdoor wordt de code van een worker niet geblokkeerd door bewerkelijke code van een andere worker. In plaats daarvan worden beide sets met code parallel uitgevoerd. Het gevolg is dat code op de achtergrond kan worden uitgevoerd door een worker terwijl de hoofdthread van de toepassing beschikbaar blijft op het scherm continu bij te werken.
De mogelijkheid om meerdere sets met code-instructies gelijktijdig uit te voeren wordt gelijktijdige uitvoering genoemd.
Opmerking: het gebruik van workers voor gelijktijdige uitvoering wordt zowel ondersteund in Flash Player als in AIR op desktopplatforms. Voor mobiele platformen wordt gelijktijdigheid ondersteund in AIR bij zowel Android als iOS. Met de statische eigenschap isSupported kunt u controleren of gelijktijdige uitvoering wordt ondersteund, voordat u dit gaat uitproberen.
U kunt niet rechtstreeks Worker-instanties maken door de Worker()
-constructor aan te roepen. Bij systeemcontexten waarin het gelijktijdige gebruik van workers wordt ondersteund, wordt de worker die is gekoppeld aan het SWF-hoofdbestand (oftewel de primordial worker) bij het opstarten automatisch door de runtime gemaakt.
Elke volgende worker wordt gemaakt op basis van een afzonderlijk SWF-bestand. Als u een nieuwe instantie van de Worker-klasse wilt maken, moet u een ByteArray met de bytes van het SWF-bestand van de 'worker op de achtergrond' doorgeven als argument bij de methode createWorker()
van de WorkerDomain-klasse. Er zijn drie manieren om de bytes van een SWF-bestand op te halen:
-
Gebruik de [Embed]-metatag om het SWF-bestand als een ByteArray in te sluiten in de toepassing:
// 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(); }
-
Laad een extern SWF-bestand met behulp van 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(); }
-
Gebruik een enkel SWF-bestand voor zowel de 'primordial worker' als voor de worker op de achtergrond.
// 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 } }
Workers worden afzonderlijk van elkaar uitgevoerd en hebben geen toegang tot hetzelfde geheugen, variabelen of code. Er zijn echter drie methoden om berichten en gegevens uit te wisselen tussen Worker-instanties:
- Gedeelde eigenschappen: elke worker beschikt over een interne set met benoemde waarden die kunnen worden ingesteld en gelezen door de worker zelf, maar ook door andere workers. Met de methode
setSharedProperty()
kunt u een waarde instellen en met de methodegetSharedProperty()
kunt u een waarde lezen. - MessageChannel: met een MessageChannel-object kunt u berichten en gegevens in één richting verzenden van de ene worker naar de andere. De code in de ontvangende worker kan luisteren naar een gebeurtenis om een melding te ontvangen zodra een bericht arriveert. Als u een MessageChannel-object wilt maken, gebruikt u de methode
createMessageChannel()
. - Deelbare ByteArray: als de eigenschap
shareable
van een ByteArray-object is ingesteld optrue
, wordt hetzelfde onderliggende geheugen gebruikt voor instanties van die ByteArray in alle workers. Omdat code in meerdere workers op hetzelfde moment toegang heeft tot het gedeelde geheugen, moet uw code de mechanismen gebruiken in de beschrijving van de eigenschapByteArray.shareable
om problemen met onverwachte gegevenswijzigingen te voorkomen.
Een aantal runtime-API's zijn niet beschikbaar voor code die in een worker op de achtergrond wordt uitgevoerd. Hierbij gaat het vooral om API's die zijn te maken hebben met gebruikersinvoer en -uitvoer, en om besturingssysteemelementen zoals vensters of sleepbewerkingen. Wanneer een API niet wordt ondersteund in alle systeemcontexten, moet u voordat u de API gebruikt, altijd eerst controleren of de API beschikbaar is in een systeemcontext met workers op de achtergrond. Gebruik hiervoor de eigenschappen isSupported
, available
en vergelijkbare eigenschappen.
Opmerking: native extensies worden niet ondersteund voor achtergrond en secundaire workers.
Workers zijn handig omdat het risico op een tragere framesnelheid doordat de hoofdthread voor rendering wordt geblokkeerd door andere code, wordt verkleind. Workers vereisen echter ook extra systeemgeheugen en CPU-gebruik, en dat gaat soms ten koste van de algehele prestaties van de toepassing. Aangezien elke worker een eigen instantie van de runtime-VM gebruikt, kan zelfs een eenvoudige worker leiden tot een aanzienlijke overhead. Wanneer u workers gebruikt, moet u uw code dan ook testen op alle doelplatforms om te voorkomen dat het systeem niet te zwaar wordt belast. Adobe raadt aan dat u niet meer dan een of twee workers op de achtergrond gebruikt in een typisch scenario.
Meer informatie
Introductie tot AS3-workers: afbeeldingen verwerken, door Shawn Blais
Multithreaded Physics: AS3-workers gebruiken voor een Physics-engine, door Shawn Blais
Verwante API-elementen
Eigenschap | Gedefinieerd door | ||
---|---|---|---|
constructor : Object
Verwijzing naar het klasseobject of de constructorfunctie van een bepaalde objectinstantie. | Object | ||
current : Worker [statisch] [alleen-lezen]
Biedt toegang tot de worker die de huidige code bevat
| Worker | ||
isPrimordial : Boolean [alleen-lezen]
Geeft aan of deze worker de 'primordial worker' is. | Worker | ||
isSupported : Boolean [statisch] [alleen-lezen]
Geeft aan of de huidige context van de runtime ondersteuning biedt voor gelijktijdige code-uitvoering van de Worker-objecten. | Worker | ||
state : String [alleen-lezen]
De huidige status in de levenscyclus van de worker. | Worker |
Methode | Gedefinieerd door | ||
---|---|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void [overschrijven]
Registreert een gebeurtenislistenerobject bij een object EventDispatcher, zodat de listener een melding van een gebeurtenis ontvangt. | Worker | ||
Maakt een nieuwe MessageChannel-instantie om berichten te versturen van de worker waarvan de methode is aangeroepen. De berichten gaan naar een andere, ontvangende worker. | Worker | ||
Verzendt een gebeurtenis naar de gebeurtenisstroom. | EventDispatcher | ||
Hiermee wordt de waarde opgehaald die in deze worker is opgeslagen met een benoemde sleutel. | Worker | ||
Controleert of het object EventDispatcher listeners heeft geregistreerd voor een specifiek type gebeurtenis. | EventDispatcher | ||
Geeft aan of voor een object een opgegeven eigenschap is gedefinieerd. | Object | ||
Geeft aan of een instantie van de klasse Object zich in de prototypeketen van het object bevindt dat als parameter is opgegeven. | Object | ||
Geeft aan of de opgegeven eigenschap bestaat en kan worden opgesomd. | Object | ||
[overschrijven]
Verwijdert een listener uit het object EventDispatcher. | Worker | ||
Stelt de beschikbaarheid van een dynamische eigenschap voor lusbewerkingen in. | Object | ||
Biedt een benoemde waarde die beschikbaar is voor code die in het SWF-bestand van de worker wordt uitgevoerd. | Worker | ||
Start de uitvoering van de worker. | Worker | ||
Stopt de uitvoering van de code van deze worker. | Worker | ||
Geeft de tekenreeksweergave van dit object weer, geformatteerd volgens de locatiespecifieke conventies. | Object | ||
Retourneert een tekenreeksrepresentatie van het opgegeven object. | Object | ||
Retourneert de primitieve waarde van het opgegeven object. | Object | ||
Controleert of een gebeurtenislistener is geregistreerd bij dit object EventDispatcher of een van de voorouders voor het opgegeven type gebeurtenis. | EventDispatcher |
Gebeurtenis | Overzicht | Gedefinieerd door | ||
---|---|---|---|---|
[uitgezonden gebeurtenis] Wordt verzonden wanneer Flash Player of de AIR-toepassing de besturingssysteemfocus krijgt en actief wordt. | EventDispatcher | |||
[uitgezonden gebeurtenis] Wordt verzonden wanneer Flash Player of de AIR-toepassing de systeemfocus verliest en inactief wordt. | EventDispatcher | |||
Wordt verzonden wanneer de waarde van de state-eigenschap van de worker verandert. | Worker |
current | eigenschap |
isPrimordial | eigenschap |
isPrimordial:Boolean
[alleen-lezen] Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Geeft aan of deze worker de 'primordial worker' is.
De primordial worker is de worker waarin het oorspronkelijke SWF-bestand wordt uitgevoerd. Deze worker beheert de rendering van het scherm.
Deze eigenschap kan worden gebruikt om een toepassingarchitectuur op te zetten waarbij de 'primordial worker' en de worker op de achtergrond twee instanties van hetzelfde SWF-bestand vormen. Het alternatief is om de code zo te structureren dat de worker op de achtergrond andere code gebruikt en om deze code te compileren naar een ander SWF-bestand dan de 'primordial worker'.
Implementatie
public function get isPrimordial():Boolean
isSupported | eigenschap |
isSupported:Boolean
[alleen-lezen] Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Geeft aan of de huidige context van de runtime ondersteuning biedt voor gelijktijdige code-uitvoering van de Worker-objecten.
Als gelijktijdige uitvoering beschikbaar is, wordt deze eigenschap ingesteld op true
.
Implementatie
public static function get isSupported():Boolean
state | eigenschap |
state:String
[alleen-lezen] Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
De huidige status in de levenscyclus van de worker. Mogelijke waarden voor deze eigenschap zijn gedefinieerd in de WorkerState-klasse.
Implementatie
public function get state():String
Verwante API-elementen
addEventListener | () | methode |
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Registreert een gebeurtenislistenerobject bij een object EventDispatcher, zodat de listener een melding van een gebeurtenis ontvangt. U kunt gebeurtenislisteners registreren op alle knooppunten in het weergaveoverzicht van een specifiek type gebeurtenis, fase of prioriteit.
Nadat het registreren van een gebeurtenislistener is voltooid, kunt u de prioriteit ervan niet wijzigen door extra aanroepen van addEventListener()
. Wanneer u de prioriteit van een listener wilt wijzigen, moet u eerst removeListener()
aanroepen. U kunt de listener opnieuw registreren met het nieuwe prioriteitsniveau.
Nadat de listener is geregistreerd, resulteren volgende aanroepen van addEventListener()
met een andere waarde voor type
of useCapture
in het maken van een afzonderlijke listenerregistratie. Wanneer u bijvoorbeeld eerst een listener registreert bij useCapture
ingesteld op true
, luistert deze alleen tijdens de vastlegfase. Wanneer u addEventListener()
opnieuw aanroept met hetzelfde listenerobject maar met useCapture
ingesteld op false
, hebt u twee afzonderlijke listeners: één die tijdens de vastlegfase luistert en één die tijdens de doel- en terugkoppelfasen luistert.
U kunt geen gebeurtenislistener registeren voor alleen de doel- of terugkoppelfase. Deze fasen worden bij de registratie gekoppeld, omdat terugkoppeling alleen van toepassing is op voorouders van het doelknooppunt.
Wanneer u een gebeurtenislistener niet langer nodig hebt, kunt u deze verwijderen door removeEventListener()
aan te roepen; anders kan dit resulteren in geheugenproblemen. Gebeurtenisluisteraars worden niet automatisch uit het geheugen verwijderd, omdat de verzamelaar met ongewenste details de luisteraar niet verwijderd zolang het verzendende object bestaat (behalve als de parameter useWeakReference
op true
is ingesteld).
Het kopiëren van een instantie EventDispatcher kopieert de daaraan gekoppelde gebeurtenislisteners. (Wanneer uw nieuwe knooppunt een gebeurtenislistener nodig heeft, moet u de listener eraan koppelen na het maken van het knooppunt.) Wanneer u echter een instantie EventDispatcher verplaatst, worden de daaraan gekoppelde listeners mee verplaatst.
Wanneer de gebeurtenislistener wordt geregistreerd op een knooppunt terwijl een gebeurtenis op dit knooppunt wordt verwerkt, wordt de gebeurtenislistener niet geactiveerd tijdens de huidige fase maar kan wel worden geactiveerd in een latere fase in de gebeurtenisstroom, zoals de terugkoppelfase.
Wanneer een gebeurtenislistener wordt verwijderd uit een knooppunt terwijl een gebeurtenis wordt verwerkt op het knooppunt, wordt deze nog steeds geactiveerd door de huidige handelingen. Nadat deze is verwijderd, wordt de gebeurtenislistener niet meer aangeroepen (tenzij deze opnieuw wordt geregistreerd voor toekomstige verwerking).
Parameters
type:String — Het type gebeurtenis.
| |
listener:Function — De listenerfunctie die de gebeurtenis verwerkt. Deze functie moet een Event-object accepteren als de enige parameter en niets retourneren, zoals in dit voorbeeld wordt getoond:
function(evt:Event):void De functie kan elke naam hebben. | |
useCapture:Boolean (default = false ) —
Bepaalt of de listener werkt in de vastleg-, doel- en terugkoppelfase. Wanneer useCapture wordt ingesteld op true , verwerkt de listener de gebeurtenis alleen tijdens de vastlegfase en niet tijdens de doel- of terugkoppelfase. Wanneer useCapture wordt ingesteld op false , verwerkt de listener de gebeurtenis alleen tijdens de doel- of terugkoppelfase. Wanneer u in alle drie de fasen naar de gebeurtenis wilt luisteren, roept u addEvenListener() tweemaal aan, één keer met useCapture ingesteld op true en één keer met useCapture ingesteld op false .
| |
priority:int (default = 0 ) — Het prioriteitsniveau van de gebeurtenislistener. De prioriteit is opgegeven door een 32-bits geheel getal. Hoe hoger het getal, hoe hoger de prioriteit. Alle listeners met een prioriteit n worden verwerkt voor listeners met een prioriteit n -1. Wanneer twee of meer listeners dezelfde prioriteit hebben, worden ze verwerkt in de volgorde waarin ze werden toegevoegd. De standaardprioriteit is 0.
| |
useWeakReference:Boolean (default = false ) — Bepaalt of de verwijzing van de listener sterk of zwak is. Een sterke verwijzing (standaard) voorkomt dat uw listener wordt opgeschoond. Een zwakke verwijzing doet dat niet. Lidfuncties op klasseniveau worden niet opgeschoond. U kunt dus |
createMessageChannel | () | methode |
public function createMessageChannel(receiver:Worker):MessageChannel
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Maakt een nieuwe MessageChannel-instantie om berichten te versturen van de worker waarvan de methode is aangeroepen. De berichten gaan naar een andere, ontvangende worker. De code in de worker die het MessageChannel-object maakt, kan hiermee berichten (in één richting) verzenden naar het opgegeven Worker-object dat is opgegeven als het receiver
-argument.
Alhoewel een MessageChannel-instantie kan worden gebruikt om berichten en gegevens van één Worker-instantie naar een andere te verzenden, moet er minimaal één MessageChannel-instantie als een gedeelde eigenschap worden doorgegeven aan een onderliggende worker. Hiertoe moet de methode setSharedProperty()
van het Worker-object worden aangeroepen.
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);
Parameters
receiver:Worker — De worker die de berichten ontvangt die via het gemaakte berichtkanaal zijn verzonden
|
MessageChannel — Het MessageChannel-object dat is gemaakt door de bewerking
|
getSharedProperty | () | methode |
public function getSharedProperty(key:String):*
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Hiermee wordt de waarde opgehaald die in deze worker is opgeslagen met een benoemde sleutel.
De code in een onderliggende worker kan deze methode aanroepen om een waarde op te halen. Deze waarde is al tijdens de constructor-fase van de SWF-hoofdklasse beschikbaar.
Parameters
key:String — De naam van de gedeelde eigenschap die moet worden opgehaald
|
* — De waarde van de gedeelde eigenschap die is opgeslagen met de opgegeven sleutel (of null als er geen waarde is opgeslagen voor de opgegeven sleutel)
|
removeEventListener | () | methode |
override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Verwijdert een listener uit het object EventDispatcher. Wanneer geen overeenkomende listener is geregistreerd bij het object EventDispatcher, heeft een aanroep van deze methode geen invloed.
Parameters
type:String — Het type gebeurtenis.
| |
listener:Function — Het listenerobject dat wordt verwijderd.
| |
useCapture:Boolean (default = false ) —
Geeft aan of de listener is geregistreerd voor de vastleg-, doel- en terugkoppelfase. Wanneer de listener is geregistreerd voor zowel de vastlegfase als de doel- en terugkoppelfase, zijn twee aanroepen van de removeEventListener() nodig om beide te verwijderen, één met useCapture ingesteld op true en één met useCapture ingesteld op false .
|
setSharedProperty | () | methode |
public function setSharedProperty(key:String, value:*):void
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Biedt een benoemde waarde die beschikbaar is voor code die in het SWF-bestand van de worker wordt uitgevoerd.
U kunt deze methode aanroepen voordat u de methode start()
van de worker aanroept. In dat geval is de gedeelde eigenschap tijdens de constructiefase al beschikbaar voor code in het SWF-bestand van de worker.
Praktisch elk object kan als waarde worden doorgegeven aan de value
-parameter. Met uitzondering van de onderstaande objecten, worden objecten die zijn doorgegeven aan de value
-parameter, niet als referentie doorgegeven. Wijzigingen die worden doorgevoerd in het object van een worker nadat setSharedProperty()
is aangeroepen, worden niet doorgevoerd in de andere worker. Het object wordt via serienummering gekopieerd naar de AMF3-indeling en vervolgens weer via serienummering omgezet als een nieuw object in de ontvangende worker. Dit is ook waarom objecten die niet via serienummering kunnen worden omgezet naar een AMF-indeling (zoals bijvoorbeeld weergaveobjecten), niet kunnen worden doorgegeven aan de value
-parameter. Voor een juiste doorgave van een aangepaste klasse moet de klassendefinitie worden geregistreerd met de functie flash.net.registerClassAlias()
of met [RemoteClass]
-metagegevens. Voor beide methoden geldt dat hetzelfde alias moet worden gebruikt voor de klassenversies van beide workers.
Er zijn vijf objecttypen die een uitzondering vormen op de regel dat objecten niet daadwerkelijk worden gedeeld door workers:
- Worker-item
- MessageChannel
- deelbare ByteArray (een ByteArray-object waarvan de eigenschap
shareable
is ingesteld optrue
- Mutex
- Condition
Wanneer u een instantie van een van deze objecten doorgeeft met de value
-parameter, beschikt elke worker over een referentie naar hetzelfde onderliggende object. Wijzigingen die in één worker worden toegepast op een instantie zijn dan direct beschikbaar in alle andere workers. Bovendien geldt dat als u eenzelfde instantie van deze objecten meerdere keren doorgeeft aan een worker met behulp van setSharedProperty()
, er niet telkens een nieuw exemplaar van het object in de ontvangende worker wordt gemaakt door de runtime. In plaats hiervan wordt dezelfde referentie opnieuw gebruikt, waardoor er minder systeemgeheugen in beslag wordt genomen.
Als u deze methode aanroept met de waarden null
of undefined
voor het value
-argument, worden alle vooraf ingestelde waarden voor het opgegeven key
-argument gewist. Als u een waarde op deze manier opschoont, worden ook de referenties naar deze waarde verwijderd, zodat ook deze gegevens worden opgeschoond.
U kunt elke tekenreekswaarde gebruiken in het key-argument. Deze gedeelde eigenschappen zijn beschikbaar voor elke willekeurige code die toegang heeft tot een worker. Om te voorkomen dat u per ongeluk een waarde overschrijft, kunt u een voorvoegsel, achtervoegsel of vergelijkbaar item gebruiken om unieke sleutelnamen te maken.
Parameters
key:String — De naam waarmee de gedeelde eigenschap wordt opgeslagen.
| |
value:* — De waarde van de gedeelde eigenschap.
|
Verwante API-elementen
start | () | methode |
public function start():void
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Start de uitvoering van de worker. De runtime maakt de thread van de worker en roept de constructor van de SWF-hoofdklasse van de worker aan.
Deze bewerking is asynchroon. Nadat de startprocedure van de worker volledig is uitgevoerd, wordt de state
-eigenschap ingesteld op WorkerState.RUNNING
, waarna een workerState
-gebeurtenis wordt verzonden.
terminate | () | methode |
public function terminate():Boolean
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Stopt de uitvoering van de code van deze worker. Als u deze methode aanroept, wordt alle huidige ActionScript-code in het SWF-bestand van de worker afgebroken.
Geretourneerde waardeBoolean — true als de code in de worker werd uitgevoerd en vervolgens onderbroken, of false als de worker nog niet was gestart
|
workerState | Gebeurtenis |
flash.events.Event
eigenschap Event.type =
flash.events.Event.WORKER_STATE
Taalversie: | ActionScript 3.0 |
Runtimeversies: | Flash Player 11.4, AIR 3.4 |
Wordt verzonden wanneer de waarde van de state
-eigenschap van de worker verandert.
Event.WORKER_STATE
definieert de waarde van de type
-eigenschap van een workerState
-gebeurtenisobject.
Deze gebeurtenis heeft de volgende eigenschappen:
Eigenschap | Waarde |
---|---|
bubbles | false |
cancelable | false ; er is geen standaardgedrag om te annuleren. |
currentTarget | Het object dat het gebeurtenisobject actief verwerkt met een gebeurtenislistener. |
target | Het object dat deze gebeurtenis heeft verzonden. |
In dit voorbeeld worden drie ActionScript-klassen toegepast: WorkerExample is de hoofdklasse en dus ook de bovenliggende worker. Met de BackgroundWorker-klasse worden de bewerkingen op de achtergrond uitgevoerd. Deze klasse wordt gecompileerd als hoofdklasse van de SWF-code van de worker op de achtergrond. CountResult is een aangepaste klasse waarmee gegevens tussen beide workers als een enkel object worden doorgegeven, en niet als meerdere waarden.
In dit voorbeeld telt de worker op de achtergrond in een lus, tot aan een waarde die door de bovenliggende worker is opgegeven. Terwijl de worker de code uitvoert, stuurt deze voortgangsberichten naar de bovenliggende worker. Wanneer de telling gereed is, stuurt de worker op de achtergrond een bericht naar de bovenliggende worker om aan te geven dat de bewerkingen zijn afgerond en in hoeveel tijd dat is gebeurd.
De WorkerExample-klasse is de SWF-hoofdklasse en dus ook de hoofdklasse van de 'primordial worker'. In de methode initialize()
wordt de worker op de achtergrond gemaakt op basis van de bytes van de BackgroundWorker-klasse. Deze bytes zijn ingesloten met een [Embed]
-tag.
Nadat de worker op de achtergrond is gemaakt door het aanroepen van WorkerDomain.createWorker()
, worden de communicatiemogelijkheden tussen beide workers ingesteld door de code. Eerst maakt de code een set van MessageChannel-objecten. De code geeft deze objecten door aan de worker op de achtergrond door de methode setSharedProperty()
aan te roepen. Tot slot registreert de code de workerState
-gebeurtenis van het Worker-object op de achtergrond, waarna de worker wordt gestart door de start()
-methode aan te roepen.
Terwijl de worker op de achtergrond zijn bewerkingen uitvoert, stuurt deze voortgangsberichten (en het uiteindelijke resultaat) naar de bovenliggende worker. De bovenliggende worker gebruikt deze informatie om de voortgangsbalk en de tekstindicator bij te werken.
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; } } }
Met de methode initialize()
worden de MessageChannel-objecten ontvangen die door de bovenliggende worker zijn doorgegeven. Deze objecten worden toegepast in de communicatie tussen beide workers.
De bovenliggende worker roept de methode send()
aan op het commandChannel
-berichtkanaal om een bericht te verzenden. In de worker op de achtergrond wordt vervolgens de channelMessage
-gebeurtenis verzonden door de runtime. Hiertoe wordt de methode handleCommandMessage()
aangeroepen.
Het echte werk van de worker op de achtergrond vindt plaats in de methode count()
. Terwijl de worker op de achtergrond de telling uitvoert, stuurt deze voortgangsberichten door de methode send()
aan te roepen op het MessageChannel-object progressChannel
. Als de worker gereed is met tellen, roept het de methode send()
aan op het MessageChannel-object resultChannel
.
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()
aanroepen en dezelfde aliasnaam gebruiken.
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. Aangezien een extern SWF-bestand dat Actionscript-code bevat niet dynamisch kan worden geladen, moet het externe SWF-bestand als een gestript SWF-bestand worden doorgegeven aan de worker. 2. Het insluiten van SWF-bestanden (die ABC-code bevatten) met de code [Embed] werkt niet op iOS. Elke volgende worker wordt gemaakt op basis van een afzonderlijk SWF-bestand. Als u een nieuwe instantie van de Worker-klasse wilt maken, moet u een ByteArray met de bytes van het SWF-bestand van de 'worker op de achtergrond' doorgeven als argument bij de methode createWorker()
van de WorkerDomain-klasse.
Er zijn twee algemene manieren om hiervoor toegang te krijgen tot de bytes van een SWF-bestand op iOS: ten eerste kunt u Loader
gebruiken om een extern SWF-bestand te laden, en ten tweede kunt u URLLoader
te gebruiken om SWF-bestanden te laden.
In het volgende voorbeeld wordt de Loader
-API gebruikt om het SWF-bestand te 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
wordt aangeroepen, moeten we een controlepunt voor de eigenschap isPrimordial
plaatsen in de achtergrondworker, zoals in dit voorbeeld.
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++; } } } } }
Wed Jun 13 2018, 11:42 AM Z