Creazione e gestione dei worker

Flash Player 11.4 e versioni successive, Adobe AIR 13.4 e versioni successive per le piattaforme desktop

La prima cosa da fare per utilizzare un worker per la contemporaneità di esecuzione è creare un worker di background. Per creare un worker sono necessari due tipi di oggetti. Il primo è un'istanza worker, che creerete voi. Il secondo è un oggetto WorkerDomain, che serve per creare il Worker e gestire gli oggetti Worker in esecuzione nell'applicazione.

Quando il runtime viene caricato, esso crea automaticamente l'oggetto WorkerDomain. Il runtime crea automaticamente anche un worker per il file swf principale dell'applicazione. Il primo worker creato è conosciuto come worker primordiale .

Poiché esiste un solo oggetto WorkerDomain per ogni applicazione, potete accedere all'istanza WorkerDomain utilizzando la proprietà statica WorkerDomain.current .

In qualsiasi momento, potete accedere all'istanza corrente del Worker (il worker in cui il codice corrente viene eseguito) utilizzando la proprietà statica Worker.current .

Creazione di un oggetto Worker da un file swf

Così come il file swf principale viene eseguito all'interno del worker primordiale, un worker di background esegue il codice di un solo file swf. Per utilizzare un worker di background, dovete creare e compilare il codice del worker come file swf. Per creare il worker di background, il worker principale deve poter accedere ai byte di tale file swf come oggetto ByteArray. Per creare effettivamente il worker, passate l'oggetto ByteArray al metodo createWorker() dell'oggetto WorkerDomain.

Sono tre i metodi principali per compilare il file swf del worker di background come un oggetto ByteArray:

Incorporare il file swf del worker

Usate il metatag [Embed] per incorporare il file swf del worker nel file swf principale come un oggetto ByteArray:

[Embed(source="../swfs/BgWorker.swf", mimeType="application/octet-stream")] 
private static var BgWorker_ByteClass:Class; 
private function createWorker():void 
{ 
    var workerBytes:ByteArray = new BgWorker_ByteClass(); 
    var bgWorker:Worker = WorkerDomain.current.createWorker(workerBytes); 
     
    // ... set up worker communication and start the worker 
}

Il file swf del worker viene compilato nel file swf principale come una sottoclasse ByteArray denominata BgWorker_ByteClass. Creando un'istanza di tale classe, otterrete un oggetto ByteArray precompilato con i byte del file swf del worker.

Caricare un file swf esterno del worker

Usate un oggetto URLLoader per caricare un file swf esterno. Il file swf deve provenire dallo stesso dominio di sicurezza, ad esempio, un file swf caricato dallo stesso dominio Internet del file swf principale o incluso nel pacchetto di un'applicazione AIR.

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); 
     
    // ... set up worker communication and start the worker 
}

Quando URLLoader finisce di caricare il file swf, i byte del file swf risultano disponibili nella proprietà data dell'oggetto URLLoader ( event.target.data nell'esempio).

Usare il file swf principale come file swf del worker

Potete usare un solo file swf come swf principale e swf worker. Utilizzate la proprietà loaderInfo.bytes della classe di visualizzazione principale per accedere ai byte del file swf.

// 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 or the background worker 
    if (Worker.current.isPrimordial) 
    { 
        // create a background worker 
        var bgWorker:Worker = WorkerDomain.current.createWorker(swfBytes); 
         
        // ... set up worker communication and start the worker 
    } 
    else // entry point for the background worker 
    { 
        // set up communication between workers using getSharedProperty() 
        // ... (not shown) 
         
        // start the background work 
    } 
}

Se impiegate questa tecnica, usate un'istruzione if per diversificare il codice del file swf all'interno del costruttore della classe principale o di un metodo che chiama. Per determinare se il codice viene eseguito nel worker principale o nel worker di background, verificate la proprietà corrente isPrimordial dell'oggetto Worker, come illustrato nell'esempio.

Avvio dell'esecuzione di un worker

Una volta creato un worker, potete avviare l'esecuzione del suo codice chiamando il metodo start() dell'oggetto Worker. L'operazione start() non si avvia immediatamente. Per sapere quando il worker è in esecuzione, registrate un listener per l'evento workerState dell'oggetto Worker. Tale evento viene inviato quando l'oggetto Worker passa da uno stato all'altro nel suo ciclo di vita, ad esempio quando inizia a eseguire il proprio codice. Nel gestore dell'evento workerState , verificate che la proprietà state dell'oggetto Worker sia WorkerState.RUNNING . A questo punto, il worker è in esecuzione e la funzione di costruzione della sua classe principale è stata avviata. Il codice elencato di seguito riporta un esempio di registrazione all'evento workerState e di chiamata al metodo start() :

// 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(); 
private function workerStateHandler(event:Event):void 
{ 
    if (bgWorker.state == WorkerState.RUNNING) 
    { 
        // The worker is running. 
        // Send it a message or wait for a response. 
    } 
}

Gestione dell'esecuzione del worker

Potete accedere in qualsiasi momento alla serie di worker in esecuzione nella vostra applicazione utilizzando il metodo listWorkers() della classe WorkerDomain. Questo metodo restituisce la serie di worker la cui proprietà state è WorkerState.RUNNING , incluso il worker primordiale. Se un worker non è stato avviato o se la sua esecuzione è già stata interrotta, non è incluso nell'elenco.

Se un worker non vi serve più, potete chiamare il metodo terminate() dell'oggetto Worker per chiudere il worker e liberare la memoria da esso impiegata, così come altre risorse di sistema.