Skip to main content
非同期 API とは、素早く戻る API のことで、非同期タスクを開始し、タスクが終了した後に結果が返されます。 従来、ゲームは完了コールバックを使用する場合、どのスレッドが非同期タスクを実行し、どのスレッドが結果を返すかについて、ほとんど制御できませんでした。 一部のゲームは、スレッド同期の必要性を避けるために、ヒープのセクションを単一のスレッドからのみ触れるように設計されています。 完了コールバックがゲームが制御するスレッドから呼び出されない場合、非同期タスクの結果で共有状態を更新するにはスレッド同期が必要になります。 XSAPI C API は、XblSocialGetSocialRelationshipsAsync()XblProfileGetUserProfileAsync()XblAchievementsGetAchievementsForTitleIdAsync() のような非同期 API 呼び出しを行う際に、開発者に直接的なスレッド制御を提供する新しい非同期 C API を公開します。 以下は XblProfileGetUserProfileAsync API を呼び出す基本的な例です:
この呼び出しパターンを理解するには、XAsyncBlockXTaskQueueHandle の使い方を理解する必要があります。
  • XAsyncBlock は、非同期タスク完了コールバックに関するすべての情報を保持します。
  • XTaskQueueHandle を使用すると、どのスレッドが非同期タスクを実行し、どのスレッドが XAsyncBlock の完了コールバックを呼び出すかを決定できます。

XAsyncBlock

XAsyncBlock の詳細を見てみましょう。 これは次のように定義された構造体です:
XAsyncBlock には次のものが含まれます:
  • queue - 作業を実行する場所についての情報を表すハンドルである XTaskQueueHandle。これが設定されていない場合、デフォルトキューが使用されます。
  • context - コールバック関数にデータを渡すことができます。
  • callback - 非同期作業が完了した後に呼び出されるオプションのコールバック関数。コールバックを指定しない場合は、XAsyncGetStatusXAsyncBlock の完了を待ってから結果を取得できます。
呼び出す非同期 API ごとに、ヒープ上に新しい XAsyncBlock を作成する必要があります。 XAsyncBlock は、XAsyncBlock の完了コールバックが呼び出されるまで存続する必要があり、その後削除できます。
重要: XAsyncBlock は、非同期タスクが完了するまでメモリに残っている必要があります。動的に割り当てられている場合、XAsyncBlock の完了コールバックの内部で削除できます。

非同期タスクの待機

非同期タスクが完了したことは、次のいくつかの異なる方法で確認できます:
  • XAsyncBlock の完了コールバックが呼び出される。
  • XAsyncGetStatus を true で呼び出して、完了するまで待機する。
XAsyncGetStatus では、XAsyncBlock の完了コールバックが実行された後で非同期タスクは完了したとみなされますが、XAsyncBlock の完了コールバックはオプションです。 非同期タスクが完了したら、結果を取得できます。

非同期タスクの結果の取得

結果を取得するには、ほとんどの非同期 API 関数には、対応する [Name of Function]Result 関数があり、非同期呼び出しの結果を受け取ります。 例のコードでは、XblProfileGetUserProfileAsync に対応する XblProfileGetUserProfileResult 関数があります。 この関数を使用して関数の結果を取得し、それに応じて動作させることができます。 結果の取得に関する詳細については、各非同期 API 関数のドキュメントを参照してください。

XTaskQueueHandle

XTaskQueueHandle を使用すると、どのスレッドが非同期タスクを実行し、どのスレッドが XAsyncBlock の完了コールバックを呼び出すかを決定できます。 ディスパッチモードを設定することで、これらの操作を行うスレッドを制御できます。 利用可能なディスパッチモードは 3 つあります:
  • Manual - 手動キューは自動的にディスパッチされません。開発者が任意のスレッドでディスパッチする必要があります。これは、非同期呼び出しの作業側またはコールバック側のいずれかを特定のスレッドに割り当てるために使用できます。これについては後ほど詳しく説明します。
  • Thread Pool - スレッドプールを使用してディスパッチします。スレッドプールは呼び出しを並行して実行し、スレッドプールのスレッドが利用可能になるにつれて、キューから順番に呼び出しを取り出して実行します。これは最も使いやすいですが、使用するスレッドに対する制御が最も少ないです。
  • Serialized Thread Pool - スレッドプールを使用してディスパッチします。スレッドプールは呼び出しをシリアルに実行し、単一のスレッドプールスレッドが利用可能になるにつれて、キューから順番に呼び出しを取り出して実行します。
  • Immediate - キューに入れられた作業を、送信されたスレッドから直ちにディスパッチします。
新しい XTaskQueueHandle を作成するには、XTaskQueueCreate を呼び出す必要があります。 例:
この関数は 2 つの XTaskQueueDispatchMode パラメータを取ります。 XTaskQueueDispatchMode には 3 つの可能な値があります:
workDispatchMode は非同期作業を処理するスレッドのディスパッチモードを決定し、completionDispatchMode は非同期操作の完了を処理するスレッドのディスパッチモードを決定します。 XTaskQueueHandle を作成したら、それを XAsyncBlock に追加するだけで、作業関数と完了関数のスレッド処理を制御できます。 XTaskQueueHandle の使用が終わったら、通常はゲーム終了時に、XTaskQueueCloseHandle で閉じることができます:
呼び出し例:

XTaskQueueHandle の手動ディスパッチ

XTaskQueueHandle の作業または完了キューに手動キューディスパッチモードを使用した場合、手動でディスパッチする必要があります。 作業キューと完了キューの両方が次のように手動でディスパッチされるように設定された XTaskQueueHandle が作成されたとしましょう:
XTaskQueueDispatchMode::Manual が割り当てられた作業をディスパッチするには、XTaskQueueDispatch 関数でディスパッチする必要があります。
呼び出し例
  • queue - 作業をディスパッチするキュー。
  • port - XTaskQueuePort 列挙型のインスタンス。
  • timeoutInMs - ミリ秒単位のタイムアウトを表す uint32_t。
XTaskQueuePort 列挙型で定義される 2 つのコールバックタイプがあります:

XTaskQueueDispatch を呼び出すタイミング

キューが新しい項目を受け取ったかどうかを確認するには、XTaskQueueRegisterMonitor を呼び出してイベントハンドラを設定し、作業または完了がディスパッチ可能になったことをコードに知らせることができます。
XTaskQueueRegisterMonitor は次のパラメータを取ります:
  • queue - コールバックを送信する非同期キュー。
  • callbackContext - 送信コールバックに渡されるデータへのポインタ。
  • callback - 新しいコールバックがキューに送信されるときに呼び出される関数。
  • token - コールバックを削除するために XTaskQueueUnregisterMonitor の後の呼び出しで使用されるトークン。
例えば、XTaskQueueRegisterMonitor の呼び出しは次のようになります: XTaskQueueRegisterMonitor(queue, nullptr, HandleAsyncQueueCallback, &m_callbackToken); 対応する XTaskQueueMonitorCallback コールバックは、次のように実装できます:
そして、バックグラウンドスレッドで、この条件変数をリッスンして起動し、XTaskQueueDispatch を呼び出すことができます。

関連項目

XSAPI C API の概要 XSAPI リファレンス libHttpClient
最終更新日 2026年8月25日