建立及管理 Worker

適用於桌面平台的 Flash Player 11.4 以及更新的版本,Adobe AIR 13.4 以及更新的版本

將 Worker 做為並行之用的第一步,就是建立背景 Worker。您可以使用兩種物件來建立 Worker。第一種是 Worker 實體,即您所建立的內容。另一種則是 WorkerDomain 物件,此物件會在應用程式中建立 Worker 並管理執行中的 Worker 物件。

當執行階段載入時,就會自動建立 WorkerDomain 物件。此外,執行階段也會自動為應用程式的主要 SWF 建立 Worker。第一個 Worker 又稱為「原始 Worker」。

由於應用程式只有一個 WorkerDomain 物件,因此,您可以使用靜態 WorkerDomain.current 屬性來存取 WorkerDomain 實體。

不管何時,您都可以使用靜態 Worker.current 屬性來存取目前的 Worker 實體 (目前程式碼執行所在的 Worker)。

從 SWF 建立 Worker 物件

就如同主要 SWF 在原始 Worker 內執行一樣,背景 Worker 也會執行單一 SWF 檔案的程式碼。若要使用背景 Worker,您必須將 Worker 的程式碼編寫並編譯為 SWF 檔案。若要建立背景 Worker,父 Worker 需要存取該 SWF 檔案做為 ByteArray 物件的位元組。將該 ByteArray 傳遞至 WorkerDomain 物件的 createWorker() 方法,就會實際建立 Worker。

您可以使用三種主要方式,取得背景 Worker SWF 做為 ByteArray 物件:

內嵌 Worker SWF

使用 [Embed] 中繼標籤,可將 Worker 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 
}

Worker SWF 會編譯為主要 SWF 當做 ByteArray 子類別,名為 BgWorker_ByteClass。建立該類別的實體會產生已預先填入 Worker SWF 位元組的 ByteArray。

載入外部 Worker 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 當做 Worker SWF 使用

您可以將單一 SWF 同時當做主要 SWF 和 Worker 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 或背景 Worker 中執行,請檢查目前 Worker 物件的 isPrimordial 屬性,如範例所示。

開始執行 Worker

一旦建立 Worker,您就能透過呼叫 Worker 物件的 start() 方法,開始執行它的程式碼。 start() 作業不會立即進行。若要得知 Worker 何時執行,請為 Worker 物件的 workerState 事件註冊一個偵聽程式。當 Worker 物件切換效期中的狀態時,就會傳送該事件,例如開始執行程式碼的時候。在您的 workerState 事件處理常式中,請確認 Worker 物件的 state 屬性為 WorkerState.RUNNING 。此時,Worker 正在執行且其主要類別的建構函式已經執行。下列程式碼清單說明註冊 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. 
    } 
}

管理 Worker 執行

不管何時,您都可以在應用程式中使用 WorkerDomain 類別的 listWorkers() 方法來存取執行中的 Worker 集。這個方法會傳回 state 屬性為 WorkerState.RUNNING 的 Worker 集,其中包括原始 Worker。對於尚未啟動或執行已遭停止的 Worker,則不會包含在內。

如果不再需要 Worker,您可以呼叫 Worker 物件的 terminate() 方法來關閉 Worker,並且釋放它的記憶體和其他系統資源。