非同期操作

使用可能な場合、同期操作ではなく非同期操作を使用します。

同期操作は、コードの指示直後に実行され、その操作が完了してから次の操作に移行されます。そのため、同期操作はフレームループのアプリケーションコードフェーズで実行されます。同期操作に長くかかる場合、フレームループのサイズが大きくなり、ディスプレイの表示がフリーズしたり、滑らかではなくなります。

非同期操作を実行するコードは即時に実行されるとは限りません。現在の実行スレッド内のコードと他のアプリケーションコードは、実行を続行します。非同期操作のコードは、レンダリングの問題を回避しながら、できるだけ早く実行されます。場合によっては、バックグラウンドで実行され、ランタイムフレームループの一部としてまったく実行されないこともあります。最終的に、操作が完了すると、ランタイムからイベントが送出され、そのイベントが以降の作業を実行することを監視できます。

レンダリングの問題を防ぐために、非同期操作はスケジュールが指定され、分割されます。このため、非同期の操作を使用するとアプリケーションの応答性を高めることが容易になります。詳しくは、認知パフォーマンスと実際のパフォーマンスを参照してください。

ただし、非同期操作には若干のオーバーヘッドが伴います。特に、短時間で完了する操作については、非同期に実行すると余分に時間がかかる場合があります。

ランタイムでは、多くの操作が同期または非同期に固定されており、その実行方法は選択できません。ただし、Adobe AIR では、同期操作または非同期操作を選択できる 3 種類の操作があります。

  • File クラスおよび FileStream クラスの操作

    File クラスの多くの操作は、同期または非同期で実行できます。例えば、ファイルやディレクトリのコピーまたは削除を行うメソッドや、ディレクトリの内容を列挙するメソッドには、いずれも非同期バージョンがあります。これらのメソッドには、非同期バージョンの名前に付いている「Async」という接尾辞が付いています。例えば、ファイルを非同期に削除するには、File.deleteFile() メソッドではなく File.deleteFileAsync() メソッドを呼び出します。

    ファイルの読み取りまたは書き込みに FileStream オブジェクトを使用する場合、FileStream オブジェクトを開く方法によって、操作を非同期に実行するかどうかが決まります。非同期操作には FileStream.openAsync() メソッドを使用します。データの書き込みは非同期に実行されます。データの読み取りはチャンク単位で実行されるので、同時に一部のデータを使用できます。対照的に、同期モードでは、FileStream オブジェクトはファイル全体を読み取ってから、コードの実行を続行します。

  • ローカル SQL データベース操作

    ローカル SQL データベースを操作する場合、SQLConnection オブジェクトを介して実行されるすべての操作は、同期モードまたは非同期モードで実行されます。非同期操作での実行を指定するには、SQLConnection.open() メソッドではなく SQLConnection.openAsync() メソッドを使用して、データベースに対する接続を開きます。データベース操作を非同期に実行すると、バックグラウンドで実行されます。データベースエンジンはランタイムフレームループ内で一切実行されないので、データベース操作によってレンダリングの問題が発生する可能性はほとんどありません。

    ローカルの SQL データベースのパフォーマンスを改善するその他の方法については、SQL データベースのパフォーマンスを参照してください。

  • Pixel Bender スタンドアロンシェーダー

    ShaderJob クラスを使用すると、Pixel Bender シェーダーを介してイメージまたはデータセットを実行し、未処理の結果データにアクセスできます。デフォルトでは、ShaderJob.start() メソッドを呼び出すと、シェーダーは非同期に実行されます。実行は、ランタイムフレームループを使用せず、バックグラウンドで行われます。ShaderJob オブジェクトの同期実行を強制するには(これは推奨されません)、start() メソッドの最初のパラメーターに値 true を渡します。

非同期にコードを実行するこのような組み込みのメカニズム以外に、同期ではなく非同期に実行する独自のコードを構築することもできます。実行時間が長くなる可能性があるタスクを実行するコードを作成する場合、複数のパートで実行するようにコードを構築できます。コードを複数のパートに分割すると、コードの実行ブロック間にレンダリング操作を実行できるようになるので、レンダリングの問題が発生する可能性が低くなります。

コードを分割する技術の一部を次に示します。これらすべての技術の背景には、常に作業の一部のみを実行するコードを記述するという考え方が中心にあります。コードの実行内容と、作業を停止する箇所を追跡します。Timer オブジェクトなどのメカニズムを使用して、作業が残っているかどうかを繰り返しチェックし、チャンク単位で追加の作業を完了するまで実行します。

このように作業を分割するコードを構築するには、いくつかの確立したパターンがあります。次の記事およびコードライブラリでは、こうしたパターンについて説明しています。また、アプリケーションに実装するときに役立つコードも用意されています。

  • Asynchronous ActionScript Execution」(バックグラウンドの詳細といくつかの実装例が記載された Trevor McCauley による記事)

  • Parsing & Rendering Lots of Data in Flash Player」(バックグラウンドの詳細と、「ビルダーパターン」および「グリーンスレッド」という 2 つの方法の例が記載された Jesse Warden による記事)

  • Green Threads」(ソースコード例を使用して「グリーンスレッド」について説明した Drew Cummins による記事)

  • greenthreads」(ActionScript で「グリーンスレッド」を実装するための Charlie Hubbard によるオープンソースコードライブラリ。詳しくは、「greenthreads Quick Start」を参照してください)

  • 「Threads in ActionScript 3」(http://www.adobe.com/go/learn_fp_as3_threads_jp)(「疑似スレッド」技法の実装例が記載された Alex Harui による記事)