> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 設定自訂提供者範例

> 設定自訂提供者範例

本主題提供如何設定自訂非同步提供者的範例。撰寫自訂非同步提供者時，非同步方法會透過
呼叫 [XAsyncBegin](/zh-TW/reference/system/xasyncprovider/functions/xasyncbegin) 來啟動。此函式具有一個回呼
參數，用於實作例如狀態變更的處理、將回呼加入佇列，
以及觸發完成等功能。

```c++ theme={null}
struct Context
{
    uint64_t result;
};

Context* context = new Context{ 0 };
// Assume that the async block is already filled out with the completion callback and task queue.
HRESULT hr = XAsyncBegin(async, context, ProviderFuncIdentity, __FUNCTION__,
    [](XAsyncOp op, const XAsyncProviderData* providerData)
    {
        Context* context =
        reinterpret_cast<Context*>(providerData->context);
        switch (op)
        {
            case XAsyncOp::Begin:
                return XAsyncSchedule(providerData->async, 0);

            case XAsyncOp::Cleanup:
                delete context;
                break;

            case XAsyncOp::GetResult:
                memcpy(providerData->buffer, &context->result, sizeof(uint64_t));
                break;

            case XAsyncOp::DoWork:
                context->result = 12345678;
                XAsyncComplete(providerData->async, S_OK, sizeof(uint64_t));
                break;

            case XAsyncOp::Cancel:
                // This call can't be canceled.
                break;
        }

    return S_OK;
});
```

這裡有許多內容需要說明，但基本概念很簡單：
呼叫 `XAsyncBegin`，並提供一個[提供者回呼](/zh-TW/reference/system/xasyncprovider/functions/xasyncprovider)
來處理不同的狀態變更。請回想一下，非同步
區塊包含要使用的工作佇列以及選用的
完成回呼實作。接著，回呼必須處理非同步工作執行階段的[五種不同
案例](/zh-TW/reference/system/xasyncprovider/enums/xasyncop)，如下表所示。

| 提供者案例 | 職責 |
| - | - |
| `Begin` | 由 `XAsyncBegin` 的呼叫立即呼叫。此案例負責將非同步工作回呼排程到工作佇列上。這是透過呼叫 [XAsyncSchedule](/zh-TW/reference/system/xasyncprovider/functions/xasyncschedule) 來處理。它會將此回呼加入佇列，以透過工作佇列的工作連接埠，以 `DoWork` 案例再次執行。 |
| `Cleanup` | 在非同步工作即將完成時呼叫，此時可刪除為追蹤而建立的任何內部資料。在前述範例程式碼中，此案例會清除為追蹤結果資料而配置的 `Context` 結構。 |
| `GetResult` | 在使用者呼叫 [XAsyncGetResult](/zh-TW/reference/system/xasyncprovider/functions/xasyncgetresult) 時呼叫。接著，此案例必須寫入傳遞給此案例的輸出緩衝區。因此，原始的非同步結果必須已儲存在某處。前述範例程式碼將其儲存在 `Context` 結構中。<br /><br />從非同步工作傳回資料的非同步 Microsoft Game Development Kit (GDK) API 函式，會在內部呼叫 `XAsyncGetResult`，並將該資料轉換為適合呼叫端的形式。我們建議使用此方式來處理結果。 |
| `DoWork` | 透過已分派其工作連接埠的工作佇列呼叫。這表示此回呼的堆疊框架會依據工作佇列的設定方式，在預期的執行緒上執行。任何工作都應在此執行。<br /><br />在 [XAsyncRun](/zh-TW/reference/system/xasync/functions/xasyncrun) 的內部非同步提供者實作中，這是它執行傳入之工作回呼的位置。對於自訂提供者，工作可以直接在回呼中完成，或使用某種自訂方法來封裝功能。<br /><br />工作完成時，必須呼叫 [XAsyncComplete](/zh-TW/reference/system/xasyncprovider/functions/xasynccomplete)。此函式會執行兩項工作。首先，它會藉由提供資料大小來指定是否需要任何輸出資料。如果提供大於零的值，就會配置內部緩衝區供 `GetResult` 案例寫入。其次，它會將完成回呼的呼叫加入佇列，以在工作佇列的完成連接埠上執行。傳遞給 `XAsyncComplete` 的完成狀態碼，會成為呼叫 [XAsyncGetStatus](/zh-TW/reference/system/xasync/functions/xasyncgetstatus) 時傳回的代碼。 |
| `Cancel` | 由外部呼叫 [XAsyncCancel](/zh-TW/reference/system/xasync/functions/xasynccancel) 觸發。如果未實作此案例，則不會發生任何事。若要允許取消，提供者必須能夠向任何正在執行的工作發出停止訊號。接著，`DoWork` 案例必須以 `E_ABORT` 狀態呼叫 `XAsyncComplete`。 |

## 參考 API 文件

* [XAsyncProvider (API 內容)](/zh-TW/reference/system/xasyncprovider/xasyncprovider_members)
  * 函式
    * [XAsyncBegin](/zh-TW/reference/system/xasyncprovider/functions/xasyncbegin)
    * [xasyncprovider](/zh-TW/reference/system/xasyncprovider/functions/xasyncprovider)
    * [XAsyncSchedule](/zh-TW/reference/system/xasyncprovider/functions/xasyncschedule)
    * [XAsyncGetResult](/zh-TW/reference/system/xasyncprovider/functions/xasyncgetresult)
    * [XAsyncComplete](/zh-TW/reference/system/xasyncprovider/functions/xasynccomplete)
* [xasync (API 內容)](/zh-TW/reference/system/xasync/xasync_members)
  * 函式
    * [XAsyncRun](/zh-TW/reference/system/xasync/functions/xasyncrun)
    * [XAsyncGetStatus](/zh-TW/reference/system/xasync/functions/xasyncgetstatus)
    * [XAsyncCancel](/zh-TW/reference/system/xasync/functions/xasynccancel)

## 另請參閱

[XAsyncProvider 程式庫概觀](/zh-TW/build/core-features/common/async/async-libraries/async-library-xasyncprovider)

[設定叫用方法 (範例)](/zh-TW/build/core-features/common/async/async-libraries/async-library-xasyncprovider-example-setup-invocation-methods)

[設定傳回資料 (範例)](/zh-TW/build/core-features/common/async/async-libraries/async-library-xasyncprovider-example-setup-return-data)

[設定可取消性 (範例)](/zh-TW/build/core-features/common/async/async-libraries/async-library-xasyncprovider-example-setup-cancelability)

[XAsyncProvider](/zh-TW/reference/system/xasyncprovider/xasyncprovider_members)


## Related topics

- [GDK 範例](/zh-TW/home/setup-install/samples.md)
- [玩家資料重設工具 (XblPlayerDataReset.exe)](/zh-TW/tools/tools-services/live-player-data-reset.md)
- [XR-018：使用者產生的內容](/zh-TW/publishing/certification/xr/xr-018.md)
- [XR-047 使用者設定檔存取](/zh-TW/publishing/certification/xr/xr-047.md)
- [XR-048 設定檔設定的使用](/zh-TW/publishing/certification/xr/xr-048.md)
