Pakiet | flash.system |
Klasa | public final class Worker |
Dziedziczenie | Worker EventDispatcher Object |
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Proces roboczy umożliwia wykonywanie kodu w tle — w czasie, gdy inny proces roboczy (łącznie z głównym procesem roboczym pliku SWF) wykonuje operacje. W przypadku braku procesów roboczych niektóre operacje, takie jak przetwarzanie dużego zbioru danych w pętli, zajmują tak dużo czasu, że uniemożliwiają głównemu wątkowi aplikacji odpowiednio szybkie aktualizowanie ekranu. Może to spowodować przerwy w wyświetlaniu lub blokowanie zawartości ekranu.
Procesy robocze pozwalają na wykonywanie długotrwałych lub powolnych operacji w tle. Każdy proces roboczy wykonuje kod w wątku odseparowanym do innych procesów roboczych. W ten sposób kod wykonywany przez dłuższy czas nie blokuje wykonywania kodu w innym procesie roboczym. Dzięki temu dwa zastawy kodu mogą być wykonywane równolegle. W rezultacie proces roboczy może służyć do wykonywania kodu w tle, a główny wątek aplikacji może kontynuować płynne aktualizowanie ekranu.
Możliwość jednoczesnego wykonywania wielu zestawów instrukcji kodu jest określana jako współbieżność.
Uwaga: Stosowanie procesów roboczych na potrzeby współbieżności jest obsługiwane w programie Flash Player oraz w środowisku AIR na platformach komputerowych. Na platformach przenośnych współbieżność jest obsługiwana w środowisku AIR w systemach Android i iOS. Przed próbą zastosowania współbieżności można sprawdzić, czy funkcja ta jest obsługiwana, korzystając z właściwości statycznej isSupported.
Wystąpień klasy Worker nie tworzy się przez bezpośrednie wywołanie konstruktora Worker()
. W przypadku kontekstów obsługujących stosowanie procesów roboczych na potrzeby współbieżności środowisko wykonawcze automatycznie tworzy proces roboczy powiązany z głównym plikiem SWF, określany jako pierwotny procese roboczy.
Każdy dodatkowy proces roboczy jest tworzony z oddzielnego pliku SWF. Aby utworzyć nowe wystąpienie klasy Worker, należy przekazać obiekt ByteArray z bajtami pliku SWF procesu roboczego działającego w tle jako argument metody createWorker()
klasy WorkerDomain. Istnieją trzy typowe metody uzyskiwania dostępu do bajtów pliku SWF stosowane w takich sytuacjach:
-
Użycie znacznika meta [Embed] i osadzenie pliku SWF w aplikacji jako obiektu ByteArray:
// 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(); }
-
Wczytanie zewnętrznego pliku SWF przy użyciu klasy 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(); }
-
Użycie pojedynczego pliku SWF jako pierwotnego procesu roboczego i procesu roboczego działającego w tle:
// 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 } }
Procesy robocze są odizolowane od innych procesów roboczych i nie mają dostępu do tych samych zasobów pamięci, zmiennych i kodu. Dostępne są trzy mechanizmy umożliwiające przekazywanie komunikatów i danych między wystąpieniami procesów klasy Worker:
- Właściwości współużytkowane: Każdy proces roboczy zawiera własny zestaw nazwanych wartości, które można ustawić i odczytać z poziomu danego procesu roboczego lub innych procesów roboczych. Metoda
setSharedProperty()
pozwala ustawić wartość, a metodagetSharedProperty()
umożliwia odczytanie wartości. - MessageChannel: Obiekt MessageChannel umożliwia jednokierunkowe wysyłanie komunikatów i danych między procesami roboczymi. Kod w odbierającym procesie roboczym może wykrywać zdarzenia powiadamiające o nowych komunikatach. Obiekt MessageChannel można utworzyć przy użyciu metody
createMessageChannel()
. - Współużytkowany obiekt ByteArray: Jeśli właściwość
shareable
obiektu ByteArray ma wartośćtrue
, dla wystąpień tego obiektu ByteArray we wszystkich procesach roboczych jest używana ta sama pamięć podstawowa. Kod wielu procesów roboczych może jednocześnie korzystać z pamięci współużytkowanej, dlatego w kodzie należy zastosować mechanizm przedstawiony w opisie właściwościByteArray.shareable
. Pozwoli to uniknąć problemów wynikających z nieoczekiwanych zmian danych.
W przypadku kodu wykonywanego w procesie roboczym działającym w tle niektóre interfejsy API czasu wykonywania są niedostępne. Dotyczy to głównie interfejsów API powiązanych z mechanizmami wejścia i wyjścia danych lub elementami systemu operacyjnego, takimi jak okna oraz przeciąganie. Przed użyciem interfejsu API nieobsługiwanego w pewnych kontekstach należy za pomocą właściwości isSupported
, available
lub podobnej sprawdzić, czy interfejs API jest dostępny w kontekście procesu roboczego działającego w tle.
Uwaga: rozszerzenia natywne nie są obsługiwane dla procesów roboczych działających w tle oraz wtórnych.
Przydatność procesów roboczych polega na możliwości redukcji prawdopodobieństwa pominięcia klatek animacji spowodowanego blokowaniem głównego wątku renderującego przez inny kod. Jednak procesy robocze wymagają większej ilości pamięci systemowej i zwiększają obciążenie procesora, co może mieć negatywny wpływ na ogólną wydajność aplikacji. Każdy proces roboczy używa własnego wystąpienia maszyny wirtualnej środowiska wykonawczego, dlatego nawet niewielki obiekt może wprowadzać duży narzut związany z dodatkowymi operacjami. Wprowadzając do kodu procesy robocze, należy go przetestować na wszystkich platformach docelowych i upewnić się, że obciążenie systemu nie jest za duże. Firma Adobe zaleca, aby w typowych sytuacjach nie używać więcej niż dwóch procesów roboczych działających w tle.
Więcej informacji
Wprowadzenie do procesów roboczych w języku ActionScript 3: Przetwarzanie obrazu, autor: Shawn Blais
Fizyka wielowątkowa: Używanie procesów roboczych ActionScript 3 jako mechanizmu obsługi fizyki — Shawn Blais
Powiązane elementy interfejsu API
Właściwość | Zdefiniowane przez | ||
---|---|---|---|
constructor : Object
Odwołanie do obiektu klasy lub funkcji konstruktora, dotyczące danej instancji obiektu. | Object | ||
current : Worker [statyczny] [tylko do odczytu]
Umożliwia dostęp do procesu roboczego, który zawiera bieżący kod.
| Worker | ||
isPrimordial : Boolean [tylko do odczytu]
Określa, czy dany proces roboczy jest pierwotnym procesem roboczym. | Worker | ||
isSupported : Boolean [statyczny] [tylko do odczytu]
Wskazuje, czy bieżący kontekst środowiska wykonawczego obsługuje obiekty Worker na potrzeby współbieżnego wykonywania kodu. | Worker | ||
state : String [tylko do odczytu]
Bieżący stan cyklu życia procesu roboczego. | Worker |
Metoda | Zdefiniowane przez | ||
---|---|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void [przesłanianie]
Rejestruje obiekt detektora zdarzeń w obiekcie EventDispatcher, dzięki czemu detektor będzie otrzymywał powiadomienia o zdarzeniu. | Worker | ||
Tworzy nowe wystąpienie klasy MessageChannel na potrzeby wysyłania komunikatów z procesu roboczego, w którym metoda jest wywoływana, do innego, odbierającego procesu roboczego. | Worker | ||
Wywołuje zdarzenie, tj. kieruje je do przepływu zdarzeń. | EventDispatcher | ||
Pobiera wartość zapisaną w tym procesie roboczym z nazwanym kluczem. | Worker | ||
Sprawdza, czy obiekt EventDispatcher zawiera jakiekolwiek detektory zarejestrowane dla konkretnego typu zdarzeń. | EventDispatcher | ||
Wskazuje, czy dla obiektu zdefiniowano określoną właściwość. | Object | ||
Wskazuje, czy instancja klasy Object należy do łańcucha prototypów obiektu określonego jako parametr. | Object | ||
Wskazuje, czy określona właściwość istnieje i jest przeliczalna. | Object | ||
[przesłanianie]
Usuwa detektor z obiektu EventDispatcher. | Worker | ||
Ustawia dostępność właściwości dynamicznej używanej w pętlach. | Object | ||
Udostępnia nazwaną wartość, która jest dostępna dla kodu działającego w pliku SWF procesu roboczego. | Worker | ||
Rozpoczyna wykonywanie procesu roboczego. | Worker | ||
Zatrzymuje wykonywanie kodu procesu roboczego. | Worker | ||
Zwraca ciąg reprezentujący obiekt — sformatowany zgodnie z konwencjami właściwymi dla ustawień regionalnych. | Object | ||
Zwraca ciąg reprezentujący określony obiekt. | Object | ||
Zwraca pierwotną wartość dla określonego obiektu. | Object | ||
Sprawdza, czy detektor zdarzeń określonego typu jest zarejestrowany w tym obiekcie EventDispatcher lub jego elementach macierzystych. | EventDispatcher |
Zdarzenie | Podsumowanie | Zdefiniowane przez | ||
---|---|---|---|---|
[zdarzenie broadcast] Wywoływane, gdy program Flash Player lub aplikacja środowiska wykonawczego AIR uzyskuje fokus w systemie operacyjnym i przechodzi w stan aktywny. | EventDispatcher | |||
[zdarzenie broadcast] Wywoływane, gdy program Flash Player lub aplikacja AIR traci fokus w systemie operacyjnym i przechodzi w stan nieaktywny. | EventDispatcher | |||
Wywoływane, gdy zmienia się wartość właściwości state procesu roboczego. | Worker |
current | właściwość |
isPrimordial | właściwość |
isPrimordial:Boolean
[tylko do odczytu] Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Określa, czy dany proces roboczy jest pierwotnym procesem roboczym.
Pierwotny proces roboczy to proces roboczy, w którym działa początkowy plik SWF. Ten proces roboczy steruje renderowaniem obrazu na ekranie.
Tej właściwości można użyć podczas projektowania aplikacji, w której pierwotny proces roboczy i proces roboczy działający w tle są dwoma wystąpieniami tego samego pliku SWF. Alternatywnym sposobem jest uporządkowanie struktury kodu w taki sposób, aby proces roboczy działający w tle używał innego kodu — skompilowanego do pliku SWF innego niż dla pierwotnego procesu roboczego.
Implementacja
public function get isPrimordial():Boolean
isSupported | właściwość |
isSupported:Boolean
[tylko do odczytu] Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Wskazuje, czy bieżący kontekst środowiska wykonawczego obsługuje obiekty Worker na potrzeby współbieżnego wykonywania kodu.
Jeśli współbieżność jest dostępna, ta właściwość ma wartość true
.
Implementacja
public static function get isSupported():Boolean
state | właściwość |
state:String
[tylko do odczytu] Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Bieżący stan cyklu życia procesu roboczego. Możliwe wartości dla tej właściwości są zdefiniowane w klasie WorkerState.
Implementacja
public function get state():String
Powiązane elementy interfejsu API
addEventListener | () | metoda |
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Rejestruje obiekt detektora zdarzenia w obiekcie EventDispatcher, dzięki czemu detektor będzie otrzymywał powiadomienia o zdarzeniu. We wszystkich węzłach listy wyświetlania można rejestrować detektory zdarzeń reagujące na zdarzenia konkretnego typu, znajdujące się w określonej fazie i mające określony priorytet.
Po pomyślnym zarejestrowaniu detektora zdarzeń nie można zmienić jego priorytetu poprzez dodatkowe wywołania metody addEventListener()
. Aby zmienić priorytet detektora, należy najpierw wywołać metodę removeListener()
. Następnie można ponownie zarejestrować detektor z nowym poziomem priorytetu.
Należy pamiętać, że po zarejestrowaniu detektora późniejsze wywołania metody addEventListener()
z różnymi wartościami type
albo useCapture
powodują rejestrowanie odrębnych detektorów. Na przykład detektor zarejestrowany z parametrem useCapture
ustawionym na true
wykrywa tylko zdarzenia w fazie przechwytywania. Po ponownym wywołaniu metody addEventListener()
z tym samym obiektem detektora, ale z parametrem useCapture
ustawionym na false
będą istniały dwa odrębne detektory: jeden wykrywający zdarzenia w fazie przechwytywania, a drugi wykrywający zdarzenia w fazach miejsca docelowego i propagacji.
Nie można zarejestrować detektora zdarzeń, który wykrywałby tylko zdarzenia w fazie miejsca docelowego lub tylko zdarzenia w fazie propagacji. Te fazy są sprzężone podczas rejestracji, ponieważ propagacja zachodzi tylko w przodkach węzła miejsca docelowego.
Gdy detektor zdarzeń przestanie być potrzebny, należy go usunąć, wywołując metodę removeEventListener()
; w przeciwnym razie mogą wystąpić problemy w zarządzaniu pamięcią. Detektory zdarzeń nie są automatycznie usuwane z pamięci, ponieważ proces czyszczenia pamięci nie usuwa detektora, pod warunkiem że istnieje obiekt wywołujący (o ile dla parametru useWeakReference
ustawiona jest wartość true
).
Skopiowanie instancji klasy EventDispatcher nie powoduje skopiowania detektorów zdarzeń dołączonych do tej instancji. (Jeśli utworzono nowy węzeł, dla którego potrzebny jest detektor zdarzeń, należy dołączyć detektor po utworzeniu węzła). Jednak przeniesienie instancji klasy EventDispatcher powoduje również przeniesienia dołączonych do niej detektorów zdarzeń
Jeśli detektor zdarzeń jest rejestrowany w węźle w momencie, gdy ten węzeł przetwarza zdarzenie, detektor nie zostanie wywołany w bieżącej fazie, ale może być wywołany w późniejszej fazie przepływu zdarzeń, np. w fazie propagacji.
Jeśli detektor zdarzeń zostanie usunięty z węzła w momencie, gdy ten węzeł przetwarza zdarzenie, zostanie wywołany przez bieżące operacje. Raz usunięty detektor zdarzeń nie jest nigdy ponownie wywoływany (chyba że zostanie ponownie zarejestrowany na potrzeby dalszego etapu wykonania programu).
Parametry
type:String — Typ zdarzenia.
| |
listener:Function — Funkcja detektora, który przetwarza zdarzenie. Ta funkcja musi przyjmować obiekt Event jako swój jedyny parametr i nie może zwracać żadnych wyników, tak jak ilustruje to poniższy przykład:
function(evt:Event):void Funkcja może mieć dowolną nazwę. | |
useCapture:Boolean (default = false ) —
Określa, czy detektor działa w fazie przechwytywania, czy w fazach miejsca docelowego i propagacji. Jeżeli parametr useCapture jest ustawiony na true , wówczas detektor przetwarza zdarzenie tylko w trakcie fazy przechwytywania, a nie w trakcie fazy miejsca docelowego i propagacji. Jeżeli parametr useCapture ma wartość false , wówczas detektor przetwarza zdarzenie tylko w trakcie fazy miejsca docelowego i propagacji. W celu wykrywania zdarzenia we wszystkich trzech fazach należy wywołać metodę addEventListener dwa razy — raz z parametrem useCapture ustawionym na true , a następnie ponownie, z parametrem useCapture ustawionym na false .
| |
priority:int (default = 0 ) — Poziom priorytetu detektora zdarzeń. Priorytet ma postać 32-bitowej liczby całkowitej ze znakiem. Im wyższa jest liczba, tym wyższy priorytet. Wszystkie detektory z priorytetem n są przetwarzane przed detektorami z priorytetem n-1. Jeżeli dwa lub większa liczba detektorów ma ten sam priorytet, będą one przetwarzane w kolejności, w jakiej zostały dodane. Priorytet domyślny to 0.
| |
useWeakReference:Boolean (default = false ) — Określa, czy odwołanie do detektora jest mocne, czy słabe. Odwołanie mocne (domyślnie) zapobiega usunięciu detektora przy okazji porządkowania pamięci. Odwołanie słabe temu nie zapobiega. Funkcje składowe na poziomie klasy nie podlegają porządkowaniu pamięci, zatem można ustawić właściwość |
createMessageChannel | () | metoda |
public function createMessageChannel(receiver:Worker):MessageChannel
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Tworzy nowe wystąpienie klasy MessageChannel na potrzeby wysyłania komunikatów z procesu roboczego, w którym metoda jest wywoływana, do innego, odbierającego procesu roboczego. Kod w procesie roboczym, który tworzy obiekt MessageChannel, może go używać w celu (jednokierunkowego) wysyłania komunikatów do obiektu Worker określonego jako argument receiver
.
Wystąpienie klasy MessageChannel może służyć do wysyłania komunikatów i danych między różnymi wystąpieniami klasy Worker, jednak należy przekazać co najmniej jedno wystąpienie obiektu MessageChannel do potomnego obiektu Worker jako właściwość współużytkowaną, wywołując metodę setSharedProperty()
obiektu Worker.
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);
Parametry
receiver:Worker — Proces roboczy, który będzie odbierał komunikaty przesyłane za pośrednictwem utworzonego kanału komunikatów.
|
MessageChannel — Obiekt MessageChannel utworzony za pomocą operacji.
|
getSharedProperty | () | metoda |
public function getSharedProperty(key:String):*
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Pobiera wartość zapisaną w tym procesie roboczym z nazwanym kluczem.
Kod w potomnym procesie roboczym może wywołać tę metodę, aby pobrać wartość już w konstruktorze klasy głównej pliku SWF procesu roboczego.
Parametry
key:String — Nazwa właściwości współużytkowanej, która ma zostać pobrana.
|
* — Wartość właściwości współużytkowanej zapisana z określonym kluczem lub wartość null , jeśli dla danego klucza nie zapisano żadnej wartości.
|
removeEventListener | () | metoda |
override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Usuwa detektor z obiektu EventDispatcher. Jeśli w obiekcie EventDispatcher nie ma zarejestrowanego zgodnego detektora zdarzeń, wywołanie tej metody nie odnosi żadnego skutku.
Parametry
type:String — Typ zdarzenia.
| |
listener:Function — Obiekt detektora przeznaczony do usunięcia.
| |
useCapture:Boolean (default = false ) —
Określa, czy detektor był zarejestrowany dla fazy przechwytywania, czy dla faz miejsca docelowego i propagacji. Jeżeli detektor był zarejestrowany zarówno dla fazy przechwytywania, jak i dla fazy miejsca docelowego i propagacji, konieczne są dwa wywołania metody removeEventListener() : jedno wywołanie z parametrem useCapture ustawionym na true , a następne wywołanie z parametrem useCapture ustawionym na false .
|
setSharedProperty | () | metoda |
public function setSharedProperty(key:String, value:*):void
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Udostępnia nazwaną wartość, która jest dostępna dla kodu działającego w pliku SWF procesu roboczego.
Tę metodę można wywołać przed wywołaniem metody start()
procesu roboczego. W takiej sytuacji właściwość współużytkowana jest dostępna dla kodu w pliku SWF procesu roboczego podczas wykonywania konstruktora.
Do parametru value
można przekazać jako wartość prawie dowolny obiekt. Poza wyjątkami wskazanymi poniżej obiekty przekazywane do parametru value
nie są przekazywane przez odniesienie. Zmiany wprowadzone w obiekcie w jednym z procesów roboczych po wywołaniu metody setSharedProperty()
nie są przenoszone do innego procesu roboczego. Obiekt jest kopiowany przez serializację do formatu AMF3, a następnie deserializację w postaci nowego obiektu w odbierającym procesie roboczym. Z tego powodu obiektów, które nie umożliwiają serializacji w formacie AMF3 (w tym obiektów ekranowych), nie można przekazać do parametru value
. W celu prawidłowego przekazania obiektu klasy własnej definicja tej klasy musi zostać zrejestrowana przy użyciu funkcji flash.net.registerClassAlias()
lub metadanych [RemoteClass]
. W przypadku obu tych technik należy zastosować taki sam alias dla wersji klas obu procesów roboczych.
Istnieje pięć typów obiektów, które są wyjątkami od reguły dotyczącej braku współużytkowania obiektów między procesami roboczymi:
- Worker
- MessageChannel
- Współużytkowany obiekt ByteArray (obiekt ByteArray, którego właściwość
shareable
ma wartośćtrue
) - Mutex
- Condition
W przypadku przekazania wystąpienia tych obiektów do parametru value
każdy proces roboczy zawiera odniesienie do tego samego obiektu podstawowego. Zmiany wprowadzone w wystąpieniu w jednym procesie roboczym są natychmiast dostępne w innych procesach. Ponadto jeżeli to samo wystąpienie tych obiektów zostanie wielokrotnie przekazane przy użyciu metody setSharedProperty()
, środowisko wykonawcze nie utworzy nowej kopii obiektu w odbierającym procesie roboczym. Zamiast tego zostanie ponownie użyte to samo odniesienie, co pozwala ograniczyć użycie pamięci systemowej.
Wywołanie tej metody z wartością null
lub undefined
dla argumentu value
powoduje wyczyszczenie wcześniej ustawionej wartości dla określonego argumentu key
. Wyczyszczenie wartości w taki sposób powoduje usunięcie odniesienia do niej, co pozwala na usunięcie wartości w procesie oczyszczania pamięci.
Dla argumentu key można użyć dowolnej wartości typu String. Właściwości współużytkowane są dostępne dla każdego kodu, który ma dostęp do procesu roboczego. Aby uniknąć przypadkowego zastąpienia wartości, warto zastosować prefiksy, sufiksy lub inny mechanizm nadawania niepowtarzalnych nazw kluczy.
Parametry
key:String — Nazwa, pod którą została zapisana właściwość współużytkowana.
| |
value:* — Wartość właściwości współużytkowanej.
|
Powiązane elementy interfejsu API
start | () | metoda |
public function start():void
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Rozpoczyna wykonywanie procesu roboczego. Środowisko wykonawcze generuje wątek procesu roboczego i wywołuje konstruktor klasy głównej pliku SWF procesu roboczego.
Ta operacja jest asynchroniczna. Po zakończeniu uruchamiania procesu roboczego jego właściwość state
zmienia wartość na WorkerState.RUNNING
i proces roboczy wywołuje zdarzenie workerState
.
terminate | () | metoda |
public function terminate():Boolean
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Zatrzymuje wykonywanie kodu procesu roboczego. Wywołanie tej metody przerywa wykonywanie bieżącego kodu ActionScript w pliku SWF procesu roboczego.
ZwracaBoolean — Wartość true , jeśli wykonywanie kodu w procesie roboczym zostało przerwane, lub false , jeżeli proces roboczy w ogóle nie został uruchomiony.
|
workerState | Zdarzenie |
flash.events.Event
właściwość Event.type =
flash.events.Event.WORKER_STATE
Wersja języka: | ActionScript 3.0 |
Wersje środowiska wykonawczego: | Flash Player 11.4, AIR 3.4 |
Wywoływane, gdy zmienia się wartość właściwości state
procesu roboczego.
Event.WORKER_STATE
definiuje wartość właściwości type
obiektu zdarzenia workerState
.
To zdarzenie ma następujące właściwości:
Właściwość | Wartość |
---|---|
bubbles | false |
cancelable | false ; nie ma domyślnego zachowania, które można byłoby anulować. |
currentTarget | Obiekt przetwarzający aktywnie obiekt Event za pomocą detektora zdarzeń. |
target | Obiekt, który wywołał to zdarzenie. |
Przykład zawiera trzy klasy ActionScript: WorkerExample jest klasą główną i macierzystym procesem roboczym. BackgroundWorker to klasa wykonująca pracę w tle. Jest ona skompilowana jako klasa główna pliku SWF procesu roboczego działającego w tle. CountResult to klasa własna służąca do przekazywania danych między dwoma procesami roboczymi w postaci pojedynczego obiektu (zamiast wielu wartości).
W tym przykładzie proces roboczy działający w tle odlicza w pętli do liczby określonej przez macierzysty proces roboczy. Wraz z postępami pracy proces ten wysyła odpowiednie komunikaty do macierzystego procesu roboczego. Po zakończeniu liczenia proces roboczy działający w tle wysyła do macierzystego procesu roboczego komunikat informujący o zakończeniu działania i czasie wykonania operacji.
WorkerExample to klasa główna pliku SWF, zatem jest również klasą główną pierwotnego procesu roboczego. W metodzie initialize()
kod generuje obiekt procesu roboczego działającego w tle na podstawie bajtów klasy BackgroundWorker osadzonych za pomocą znacznika [Embed]
.
Po utworzeniu procesu roboczego działającego w tle przez wywołanie metody WorkerDomain.createWorker()
kod konfiguruje komunikację między procesami roboczymi. Najpierw tworzony jest zestaw obiektów MessageChannel. Obiekty są przekazywane do procesu roboczego działającego w tle przez wywołanie metody setSharedProperty()
. Następnie kod rejestruje zdarzenie workerState
dla obiektu Worker działającego w tle i uruchamia proces roboczy, wywołując jego metodę start()
.
Wraz z postępami pracy proces roboczy działający w tle wysyła odpowiednie komunikaty (a na końcu wyniki) do macierzystego procesu roboczego. Na podstawie tych informacji macierzysty proces roboczy aktualizuje pasek postępu i wskaźnik tekstowy.
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; } } }
W przypadku metody initialize()
proces roboczy odbiera obiekty MessageChannel przekazane przez macierzysty proces roboczy. Obiekty te służą do komunikacji między procesami roboczymi.
Macierzysty proces roboczy wywołuje metodę send()
w kanale komunikatów commandChannel
, aby wysłać komunikat. Następnie środowisko wykonawcze wywołuje w procesie roboczym działającym w tle zdarzenie channelMessage
, wywołując metodę handleCommandMessage()
.
Operacje procesu roboczego działającego w tle są realizowane w metodzie count()
. Gdy proces roboczy działający w tle kontynuuje liczenie, wysyła komunikaty o postępach do macierzystego procesu roboczego, wywołując metodę send()
obiektu progressChannel
klasy MessageChannel. Po zakończeniu liczenia wywołuje metodę send()
obiektu resultChannel
klasy MessageChannel.
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()
przy użyciu tej samej nazwy aliasu.
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. Nie działa dynamiczne wczytywanie zdalnego pliku SWF z kodem ActionScript, dlatego zdalne pliki SWF należy przekazywać do procesów roboczych jako uproszczone pliki SWF. 2. Osadzanie plików SWF (z kodem ABC) przy użyciu znacznika [Embed] nie działa w systemie iOS. Każdy dodatkowy proces roboczy jest tworzony z oddzielnego pliku SWF. Aby utworzyć nowe wystąpienie klasy Worker, należy przekazać obiekt ByteArray z bajtami pliku SWF procesu roboczego działającego w tle jako argument metody createWorker()
klasy WorkerDomain.
Istnieją dwie typowe metody uzyskiwania dostępu do bajtów pliku SWF na te potrzeby w systemie iOS: Pierwsza z nich to użycie obiektu Loader
, a druga — obiektu URLLoader
.
W poniższym przykładzie plik SWF jest wczytywany przy użyciu interfejsu API Loader
.
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
, dlatego proces roboczy tła musi zawierać test właściwości isPrimordial
(zawarty w przykładzie).
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++; } } } } }
Tue Jun 12 2018, 12:06 PM Z