Quando un'applicazione non usa i worker, il codice dell'applicazione viene eseguito in un blocco lineare di passaggi denominato
thread
di esecuzione. Il thread esegue il codice scritto da uno sviluppatore. Inoltre, esegue gran parte del codice che fa parte del runtime, in particolare quello che aggiorna lo schermo quando cambiano le proprietà degli oggetti di visualizzazione. Sebbene il codice sia scritto a blocchi quali i metodi e le classi, in fase di esecuzione viene eseguito una riga alla volta come se fosse scritto in una lunga serie di passaggi consecutivi. Considerate questo esempio ipotetico di passaggi eseguiti da un'applicazione:
-
enterFrame: il runtime chiama gli eventuali gestori di eventi
enterFrame
e ne esegue il codice, uno alla volta.
-
Evento mouse: l'utente sposta il mouse e il runtime chiama gli eventuali gestori di eventi del mouse man mano che vengono attivati i vari eventi rollover e rollout.
-
Evento Load complete: una richiesta di caricare un file xml da un URL restituisce i dati del file caricato. Il gestore di eventi viene chiamato ed esegue le proprie operazioni, leggendo il contenuto xml e creando un set di oggetti dai dati xml.
-
Evento mouse: il mouse è stato spostato di nuovo, quindi il runtime chiama i gestori di eventi mouse necessari.
-
Rendering: non vi sono altri eventi in attesa, quindi il runtime aggiorna lo schermo in base alle modifiche apportate agli oggetti di visualizzazione.
-
enterFrame: il ciclo ricomincia da capo.
Come descritto nell'esempio, i passaggi ipotetici 1-5 vengono eseguiti in sequenza, in un unico blocco di tempo denominato fotogramma. Poiché tali passaggi vengono eseguiti in sequenza in un unico thread, il runtime non può interrompere un passaggio del processo per eseguirne un altro. A una frequenza di 30 fotogrammi al secondo, il runtime ha a disposizione meno di un trentesimo di secondo per eseguire tutte queste operazioni. In molti casi, questo intervallo di tempo è sufficiente per l'esecuzione del codice e il runtime resta semplicemente in attesa durante il tempo rimanente. Tuttavia, supponete che i dati xml che vengono caricati al punto 3 siano costituiti da un struttura xml molto vasta e altamente nidificata. Quando il codice inizia a eseguire l'elaborazione ciclica del file xml e a creare gli oggetti, potrebbe essere necessario più di un trentesimo di secondo per portare a termine il lavoro. In tal caso, i passaggi successivi (risposta ai movimenti del mouse e ridisegno dello schermo) non vengono eseguiti con la tempestività che sarebbe necessaria. Ciò causa il blocco e la visualizzazione a scatti dello schermo, in quanto il suo ridisegno avviene leggermente in ritardo rispetto al movimento del mouse da parte dell'utente.
Se tutto il codice viene eseguito in uno stesso thread, vi è un solo modo per evitare occasionali blocchi e visualizzazioni a scatti dello schermo, vale a dire, evitare operazioni di lenta esecuzione, quali l'iterazione su set di dati di grandi dimensioni. I worker ActionScript offrono però un'altra soluzione. Utilizzando un worker, potete eseguire un codice con tempi di esecuzione lunghi in un worker separato. Ogni worker viene eseguito in un thread distinto, quindi il worker di background può elaborare l'operazione di lenta esecuzione all'interno del proprio thread. Ciò consente al thread di esecuzione del worker principale di ridisegnare lo schermo per ogni fotogramma senza essere bloccato da altre operazioni.
Questa capacità di eseguire più operazioni di codice simultaneamente è conosciuta come
contemporaneità di esecuzione
(in inglese "concurrency"). Quando il worker di background porta a termine il proprio lavoro, o a un determinato punto di "avanzamento" dell'operazione, potete inviare notifiche e dati al worker principale. In questo modo potete scrivere codice in grado di eseguire operazioni complesse o che richiedono molto tempo, senza che l'utente subisca blocchi dello schermo.
I worker sono utili perché limitano il rischio di riduzione della frequenza fotogrammi causata dal blocco del thread di rendering principale da parte di un altro codice. Tuttavia, i worker richiedono memoria aggiuntiva e risorse della CPU e possono di conseguenza avere un impatto sulle prestazioni generali dell'applicazione. Poiché ogni worker utilizza una propria istanza dalla macchina virtuale del runtime, anche il carico di lavoro di un worker di poca importanza può essere notevole. Quando usate i worker, provate il codice su tutte le piattaforme di destinazione per assicurarvi che il suo consumo delle risorse di sistema non sia eccessivo. Adobe consiglia di non utilizzare più di uno o due worker di background in uno scenario tipico.