跳轉到主要內容
非同步 API 是指會快速傳回,但會啟動非同步工作,並在工作完成後傳回結果的 API。 傳統上,在使用完成回呼時,遊戲幾乎無法控制由哪個執行緒執行非同步工作,以及由哪個執行緒傳回結果。有些遊戲的設計是讓堆積的某個區段只由單一執行緒存取,以避免任何執行緒同步處理的需求。如果完成回呼不是從遊戲所控制的執行緒呼叫,使用非同步工作的結果更新共用狀態就需要執行緒同步處理。 PlayFab Services SDK 公開了一個非同步 C API,讓開發人員在進行非同步 API 呼叫時能直接控制執行緒,例如 PFAuthenticationLoginWithCustomIDAsync、PFDataGetFilesAsync 或 PFProfilesGetProfileAsync。 以下是呼叫 PFProfilesGetProfileAsync 的基本範例:
若要了解此呼叫模式,您需要了解如何使用 XAsyncBlock 和 XTaskQueueHandle。 XAsyncBlock 包含與非同步工作和完成回呼相關的所有資訊。 XTaskQueueHandle 可讓您決定由哪個執行緒執行非同步工作,以及由哪個執行緒呼叫 XAsyncBlock 的完成回呼。

XAsyncBlock

讓我們詳細了解 XAsyncBlock。它是定義如下的結構:
XAsyncBlock 包含:
  • queue - XTaskQueueHandle,這是代表在何處執行某項工作之相關資訊的控制代碼。如果未設定此參數,則會使用預設佇列。
  • context - 可讓您將資料傳遞至回呼函式。
  • callback - 選擇性的回呼函式,會在非同步工作完成後呼叫。如果您未指定回呼,可以使用 XAsyncGetStatus 等候 XAsyncBlock 完成,然後再取得結果。
您應該為每個非同步呼叫在堆積上建立新的 XAsyncBlock。XAsyncBlock 必須存留到其完成回呼被呼叫為止,之後就可以將其刪除。
重要: XAsyncBlock 必須保留在記憶體中,直到非同步工作完成為止。如果它是動態配置的,可以在 XAsyncBlock 的完成回呼中將其刪除。

等候非同步工作

您可以透過兩種不同方式得知非同步工作已完成:
  • 呼叫了 XAsyncBlock 的完成回呼。
  • 以 true 呼叫 XAsyncGetStatus,以等候直到其完成。
使用 XAsyncGetStatus 時,非同步工作會在 XAsyncBlock 的完成回呼執行之後視為完成,不過 XAsyncBlock 的完成回呼是選擇性的。 非同步工作完成後,您就可以取得結果。

取得非同步工作的結果

若要取得結果,大多數非同步 API 函式都有對應的 Result 函式,用來接收非同步呼叫的結果。 在我們的範例程式碼中,PFProfilesGetProfileAsync 有對應的 PFProfilesGetProfileGetResult 函式。您可以使用此函式擷取函式的結果,並據以採取動作。 如需擷取結果的完整詳細資料,請參閱每個非同步 API 函式的文件。

XTaskQueueHandle

XTaskQueueHandle 可讓您決定由哪個執行緒執行非同步工作,以及由哪個執行緒呼叫 XAsyncBlock 的完成回呼。 您可以透過設定分派模式,控制由哪個執行緒執行這些作業。可用的分派模式有三種:
  • Manual - 手動佇列不會自動分派。由開發人員決定要在哪個執行緒上分派它們。這可用來將非同步呼叫的工作端或回呼端指派給特定執行緒。
  • Thread Pool - 使用執行緒集區進行分派。執行緒集區會平行叫用呼叫,當執行緒集區的執行緒可用時,依序從佇列中取出要執行的呼叫。Thread Pool 最容易使用,但對於使用哪個執行緒的控制程度最低。
  • Serialized Thread Pool - 使用執行緒集區進行分派。執行緒集區會依序叫用呼叫,當單一執行緒集區執行緒可用時,依序從佇列中取出要執行的呼叫。
  • Immediate - 在提交已排入佇列之工作的執行緒上立即分派該工作。
若要建立新的 XTaskQueueHandle,您需要呼叫 XTaskQueueCreate。例如:
此函式接受兩個 XTaskQueueDispatchMode 參數。XTaskQueueDispatchMode 有三個可能的值:
workDispatchMode 會決定處理非同步工作之執行緒的分派模式。completionDispatchMode 會決定處理非同步作業完成之執行緒的分派模式。 建立 XTaskQueueHandle 之後,只要將其新增至 XAsyncBlock,即可控制工作函式和完成函式的執行緒。當您使用完 XTaskQueueHandle 時 (通常是在遊戲結束時),可以使用 XTaskQueueCloseHandle 將其關閉:
呼叫範例:

手動分派 XTaskQueueHandle

如果您對 XTaskQueueHandle 的工作佇列或完成佇列使用手動佇列分派模式,就需要手動分派。假設建立了一個 XTaskQueueHandle,其工作佇列和完成佇列都設定為手動分派,如下所示:
若要分派已指派 XTaskQueueDispatchMode::Manual 的工作,請呼叫 XTaskQueueDispatch 函式。
呼叫範例:
  • queue - 要在哪個佇列上分派工作。
  • port - XTaskQueuePort 列舉的執行個體。
  • timeoutInMs - 以毫秒為單位之逾時的 uint32_t。
XTaskQueuePort 列舉定義了兩種回呼類型:

何時呼叫 XTaskQueueDispatch

若要檢查佇列何時收到新項目,您可以呼叫 XTaskQueueRegisterMonitor 來設定事件處理常式,讓您的程式碼知道工作或完成已準備好進行分派。
XTaskQueueRegisterMonitor 接受下列參數:
  • queue - 您要為其提交回呼的非同步佇列。
  • callbackContext - 指向應傳遞給提交回呼之資料的指標。
  • callback - 當新回呼提交至佇列時所叫用的函式。
  • token - 在稍後呼叫 XTaskQueueUnregisterMonitor 以移除回呼時使用的權杖。
例如,以下是對 XTaskQueueRegisterMonitor 的呼叫:
對應的 XTaskQueueMonitorCallback 回呼可能實作如下:
接著,您可以在背景執行緒中接聽此條件變數的喚醒,並呼叫 XTaskQueueDispatch。

參考

API 參考文件
最後修改於 2026年10月8日