Skip to main content
异步 API 是指一种会快速返回但会启动异步任务的 API,其结果会在任务完成后返回。 传统上,游戏对哪个线程执行异步任务、哪个线程通过完成回调返回结果几乎没有控制权。有些游戏被设计为只有一个线程访问堆的某个区域,以避免任何线程同步需求。如果完成回调不是从游戏控制的线程调用的,则使用异步任务的结果更新共享状态就需要线程同步。 PlayFab 统一 SDK 暴露了一个异步 C API,让开发者在进行异步 API 调用时可直接控制线程。 以下是一个调用 PFProfilesGetProfileAsync 的基本示例:
要理解此调用模式,您需要了解如何使用 XAsyncBlockXTaskQueueHandle XAsyncBlock 承载了与异步任务和完成回调相关的所有信息。 XTaskQueueHandle 允许您确定哪个线程执行异步任务,以及哪个线程调用 XAsyncBlock 的完成回调。

XAsyncBlock

让我们详细看一下 XAsyncBlock。它是一个定义如下的结构体:
XAsyncBlock 包含:
  • queue - 一个 XTaskQueueHandle,它是一个句柄,代表关于在哪里运行工作的信息。如果未设置此参数,则使用默认队列。
  • context - 允许您向回调函数传递数据。
  • callback - 一个可选的回调函数,将在异步工作完成后被调用。如果不指定回调,可以使用 XAsyncGetStatus 等待 XAsyncBlock 完成,然后获取结果。
您应为每次异步调用在堆上创建一个新的 XAsyncBlockXAsyncBlock 必须一直存在直到其完成回调被调用,之后才可删除。
重要事项: 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

另请参阅

最后修改于 2026年8月25日