Criando e gerenciando workers

Flash Player 11.4 e posterior, Adobe AIR 13.4 e posterior para plataformas desktop

A primeira etapa no uso do worker para simultaneidade é criar um worker de segundo plano. Use dois tipos de objetos para criar um worker. O primeiro é uma instância do worker, que é o que você criou. A outra é um objeto WorkerDomain, que cria o worker e gerencia a execução de objetos do worker em um aplicativo.

Quando o runtime é carregado, ele cria automaticamente o objeto WorkerDomain. A execução também cria automaticamente um worker para o swf principal do aplicativo. O primeiro worker é conhecido como o worker primordial .

Como há somente um objeto WorkerDomain para um aplicativo, você acessa a instância do WorkerDomain utilizando a propriedade estática WorkerDomain.current .

A qualquer momento, você pode acessar a instância atual do worker (o worker no qual o código atual está sendo executado) utilizando a propriedade estática Worker.current .

Criar um objeto worker de um swf

Assim como o swf principal é executado dentro do worker primordial, o worker de segundo plano executa o código de um único arquivo swf. Para usar um worker de segundo plano, você deve criar e compilar o código do worker como um arquivo swf. Para criar um worker de segundo plano, o worker pai precisa acessar os bytes dos arquivos swf como um objeto ByteArray. Passe o ByteArray para o método createWorker() do objeto WorkerDomain para criar o worker.

Há três modos principais de ter o worker de segundo plano swf como um objeto ByteArray:

Incorporar o swf do worker

Usar a metatag [Embed] para incorporar o swf do worker em um swf principal como um 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 
}

O swf do worker é compilado em um swf principal como uma subclasse do ByteArray nomeado como BgWorker_ByteClass. Criar uma instância dessa classe oferece a você um ByteArray previamente preenchido com os bytes do swf do worker.

Carregando um swf externo do worker

Usar um objeto URLLoader para carregar um arquivo swf externo. O arquivo swf precisa vir com o mesmo domínio de segurança, assim como um arquivo swf carregado do mesmo domínio da internet como o swf principal ou incluso no pacote de aplicativo 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 o URLLoader finaliza o carregamento do arquivo swf, os bytes do swf ficam disponíveis na propriedade data do objeto URLLoader ( event.target.data no exemplo).

Usando o swf principal como o swf do worker

Você pode usar um único swf como o swf principal e o swf do worker. Usar a propriedade loaderInfo.bytes da classe de exibição principal para acessar os bytes do 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 você utilizar essa técnica, use uma instrução if para ramificar o código do arquivo swf dentro do construtor da classe principal ou um método que ele chamar. Para determinar se o código está em execução no worker principal ou no worker de segundo plano, verifique a propriedade isPrimordial do objeto do worker atual, como apresentado no exemplo.

Iniciar uma execução do worker

Depois de criar um worker, inicie a execução do código chamando o método start() do objeto do worker. A operação start() não acontece imediatamente. Para saber quando o worker está em execução, registre um ouvinte para o evento workerState do objeto do worker. O evento é despachado quando o objeto do worker alterna estados em seu ciclo de vida, como quando inicia a execução de código. No manipulador de eventos workerState , verifique se a propriedade state do objeto do worker é WorkerState.RUNNING . Nesse ponto, o worker está sendo executado e o construtor da classe principal dele foi executado. A lista de códigos a seguir apresenta um exemplo de registro para o evento workerState e chamada do método 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. 
    } 
}

Gerenciar execução do worker

A qualquer momento você pode acessar o conjunto de workers em execução em seu aplicativo usando o método listWorkers() da classe WorkerDomain. Esse método retorna o conjunto de workers cuja propriedade state é WorkerState.RUNNING , incluindo do worker primordial. Se um worker não foi iniciado ou se sua execução já foi interrompida, ele não será incluído.

Se você não precisar mais de um worker, poderá chamar o método terminate() do objeto do worker para fechá-lo e liberar a memória e outros recursos do sistema.