ワーカーの作成と管理

Flash Player 11.4 以降、Adobe AIR 13.4 以降(デスクトッププラットフォーム向け)

並行処理のためにワーカーを使用する最初の手順は、バックグラウンドワーカーを作成することです。ワーカーを作成するには、2 種類のオブジェクトを使用します。1 つ目は Worker インスタンスです。Worker は作成対象のオブジェクトです。2 つ目は WorkerDomain オブジェクトです。WorkerDomain は、Worker を作成し、アプリケーション内で実行中の Worker オブジェクトを管理するオブジェクトです。

ランタイムがロードされるときに、WorkerDomain オブジェクトが自動的に作成されます。また、ランタイムによって、アプリケーションのメイン SWF のワーカーも自動的に作成されます。この最初のワーカーは、基本ワーカーと呼ばれます。

WorkerDomain オブジェクトはアプリケーションごとに 1 つのみ存在するので、WorkerDomain インスタンスにアクセスするには、静的な WorkerDomain.current プロパティを使用します。

現在の Worker インスタンス(現在実行中のコードが属するワーカー)には、静的な Worker.current プロパティを使用していつでもアクセスできます。

SWF からの Worker オブジェクトの作成

基本ワーカー内部でメイン SWF が実行されるのと同様に、バックグラウンドワーカーで 1 つの SWF ファイルのコードが実行されます。バックグラウンドワーカーを使用するには、ワーカーのコードを SWF ファイルとしてオーサリングし、コンパイルする必要があります。バックグラウンドワーカーを作成するには、親ワーカーで、その SWF ファイルのバイトデータに ByteArray オブジェクトとしてアクセスする必要があります。その ByteArray を WorkerDomain オブジェクトの createWorker() メソッドに渡すことで、実際にワーカーを作成します。

バックグラウンドワーカー·SWF·を·ByteArray·オブジェクトとして取得する方法は主に 3 つあります。

ワーカー SWF の埋め込み

[Embed] メタタグを使用して、ワーカー SWF を ByteArray としてメイン SWF に埋め込みます。

[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 
}

ワーカー SWF は、BgWorker_ByteClass という名前の ByteArray サブクラスとして、メイン SWF 内部にコンパイルされます。このクラスのインスタンスを作成することで、ワーカー SWF のバイトデータが事前に設定された状態の ByteArray を取得できます。

外部ワーカー SWF のロード

URLLoader オブジェクトを使用して、外部 SWF ファイルをロードします。この SWF ファイルは、メイン SWF と同じインターネットドメインからロードした SWF ファイル、AIR アプリケーションパッケージに含まれる SWF ファイルなど、同じセキュリティドメインにある必要があります。

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 
}

URLLoader で SWF ファイルのロードが完了すれば、SWF のバイトデータを URLLoader オブジェクトの data プロパティ(例では event.target.data)で取得できます。

メイン SWF をワーカー SWF として使用

1 つの SWF を、メイン SWF とワーカー SWF の両方として使用できます。メイン表示クラスの loaderInfo.bytes プロパティを使用して、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 
    } 
}

このテクニックを使用する場合、メインクラスのコンストラクター内部か、呼び出すメソッド内部で、if 文を使用して SWF ファイルのコードを分岐します。実行中のコードがメインワーカー内にあるかバックグラウンドワーカー内にあるかを判定するには、例に示すとおり、現在の Worker オブジェクトの isPrimordial プロパティを確認します。

ワーカーの実行の開始

ワーカーの作成後、Worker オブジェクトの start() メソッドを呼び出して、ワーカーのコードの実行を開始します。start() の処理はすぐには開始しません。ワーカーが実行中となっているかを把握するには、Worker オブジェクトの workerState イベントに対するリスナーを登録します。このイベントは、Worker オブジェクトのライフサイクルの状態が切り替わったとき(例えば、コードの実行を開始したとき)に送出されます。workerState イベントハンドラー内で、Worker オブジェクトの state プロパティが WorkerState.RUNNING であるかを確認します。WorkerState.RUNNING となった時点で、ワーカーは実行中であり、ワーカーのメインクラスのコンストラクターは実行済みの状態です。次のコードに、workerState イベントを登録し、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. 
    } 
}

ワーカー実行の管理

WorkerDomain クラスの listWorkers() メソッドを使用して、アプリケーション内で実行中のワーカーのセットにいつでもアクセスできます。このメソッドは、state プロパティが WorkerState.RUNNING であるワーカーのセット(基本ワーカーを含む)を返します。開始されていないワーカーや、実行が既に停止したワーカーは含まれません。

ワーカーが必要なくなった場合は、Worker オブジェクトの terminate() メソッドを呼び出してワーカーをシャットダウンし、メモリやその他のシステムリソースを解放できます。