Operacje asynchroniczne

W miarę możliwości należy stosować asynchroniczne wersje operacji zamiast synchronicznych.

Operacje synchroniczne są wykonywane, gdy tylko kod poleci ich wykonanie, a kod oczekuje na ich zakończenie. W konsekwencji takie operacje działają w fazie wykonywania kodu aplikacji w pętli klatki. Jeśli operacja synchroniczna jest wykonywana zbyt długo, wówczas operacja wydłuża czas pętli klatki, co może spowodować zatrzymanie wyświetlania lub wyświetlanie z przerwami.

Gdy kod jest wykonywany jako operacja asynchroniczna, nie musi być wykonywany natychmiast. W przypadku operacji asynchronicznych trwa wykonywanie właściwego kodu oraz innego kodu aplikacji w bieżącym wątku wykonania. Następnie środowisko wykonawcze jak najszybciej wykonuje operację, podejmując próby uniknięcia problemów z renderowaniem. W niektórych przypadkach wykonywanie odbywa się w tle i kod nie jest w ogóle wykonywany w ramach pętli klatki w środowisku wykonawczym. Gdy operacja zostanie ukończona, środowisko wykonawcze wywoła zdarzenie, a kod może wykryć to zdarzenie w celu wykonania dodatkowych operacji.

Operacje asynchroniczne są zaplanowane i dzielone w celu uniknięcia problemów z renderowaniem. W konsekwencji aplikacje, w których stosowane są asynchroniczne wersje operacji, działają dużo szybciej. Więcej informacji zawiera sekcja Wydajność subiektywna a wydajność rzeczywista .

Istnieje jednak narzut ujęty w operacjach uruchomionych asynchronicznie. Rzeczywisty czas wykonania może być dłuższy dla operacji asynchronicznych, szczególnie dotyczący operacji, których wykonanie zajmuje niewiele czasu.

W środowisku wykonawczym wiele operacji jest wykonywanych w sposób synchroniczny lub asynchroniczny i nie ma możliwości wybrania sposobu ich wykonywania. Jednak w środowisku Adobe AIR istnieją trzy typy operacji, które mogą być wykonywane synchronicznie lub asynchronicznie:

  • Operacje klasy File i FileStream

    Wiele operacji klasy File może być wykonywanych synchronicznie lub asynchronicznie. Na przykład: wszystkie metody kopiowania lub usuwania plików i katalogów oraz metody wyświetlania zawartości katalogów mają wersje asynchroniczne. Te metody mają przyrostek „Async” dodany do nazwy wersji asynchronicznej. Na przykład: w celu asynchronicznego usuwania pliku należy wywołać metodę File.deleteFileAsync() zamiast metody File.deleteFile() .

    W przypadku stosowania obiektu FileStream do odczytywania z pliku lub zapisywania do pliku sposób otwierania obiektu FileStream określa, czy operacje zapisu i odczytu będą wykonywane w sposób asynchroniczny. Dla wszystkich operacji asynchronicznych należy stosować metodę FileStream.openAsync() . Zapis danych jest wykonywany metodą asynchroniczną. Odczyt danych odbywa się porcjami, dlatego w danym momencie dostępna jest tylko jedna porcja danych. I odwrotnie — w trybie synchronicznym obiekt FileStream odczytuje cały plik zanim przystąpi do wykonywania kodu.

  • Operacje na lokalnej bazie danych SQL

    Podczas pracy z lokalną bazą danych SQL wszystkie operacje wykonywane przez obiekt SQLConnection są wykonywane w trybie synchronicznym lub asynchronicznym. W celu określenia, że operacje będą wykonywane asynchronicznie, należy otworzyć połączenie z bazą danych, korzystając z metody SQLConnection.openAsync() zamiast metody SQLConnection.open() . Jeśli operacje bazy danych działają asynchronicznie, wówczas są wykonywane w tle. Mechanizm bazy danych w ogóle nie działa w pętli klatki środowiska wykonawczego, dlatego prawdopodobieństwo, że operacje bazodanowe będą powodowały problemy z renderowaniem, jest dużo niższe.

    Dodatkowe strategie umożliwiające zwiększenie wydajności korzystania z lokalnej bazy danych SQL zawiera sekcja Wydajność bazy danych SQL .

  • Autonomiczne moduły cieniujące Pixel Bender

    Klasa ShaderJob umożliwia uruchomienie obrazu lub zestawu danych za pośrednictwem modułu cieniującego Pixel Bender oraz uzyskanie dostępu do nieprzetworzonych danych wynikowych. Domyślnie po wywołaniu metody ShaderJob.start() moduł cieniujący działa w trybie asynchronicznym. To wykonanie odbywa się w tle bez wykorzystania pętli klatki środowiska wykonawczego. W celu wymuszenia synchronicznego działania obiektu ShaderJob (co nie jest zalecane) należy przekazać true do pierwszego parametru metody start() .

Dostępne są zatem wbudowane mechanizmy umożliwiające asynchroniczne wykonywanie kodu, a oprócz tego programista może zapisywać kod w taki sposób, który zapewni jego asynchroniczne wykonywanie. W przypadku pisania kodu przeznaczonego do wykonywania potencjalnie długotrwałego zadania strukturę kodu można zdefiniować w taki sposób, aby kod był wykonywany w częściach. Jeśli kod jest podzielony na części, wówczas środowisko wykonawcze może wykonywać operacje renderowania pomiędzy blokami wykonywanego kodu, dzięki czemu występowanie problemów z renderowaniem będzie mniej prawdopodobne.

Poniżej przedstawiono kilka technik dzielenia kodu. Głównym celem tych technik jest taki zapis kodu, który w dowolnym czasie będzie gwarantował wykonanie tylko części operacji. Programista może śledzić, jakie operacje wykonuje kod oraz kiedy przestaje działać. Za pomocą mechanizmu, takiego jak obiekt Timer, programista może wielokrotnie sprawdzać, jaka część pracy została do wykonania, oraz wykonywać w porcjach dodatkowe operacje do zakończenia pracy.

Istnieje kilka predefiniowanych wzorców tworzenia struktury kodu w taki sposób, który zapewni podział operacji. Poniższe artykuły i biblioteki kodu opisują te wzorce i zawierają kod, który ułatwia implementowanie tych wzorców w aplikacjach: