> ## 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.

# XGameSaveCreateUpdate

> XGameSaveCreateUpdate

# XGameSaveCreateUpdate

创建一个更新，稍后将通过调用 [XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate) 提交。

## Syntax

```cpp theme={null}
HRESULT XGameSaveCreateUpdate(  
         XGameSaveContainerHandle container,  
         const char* containerDisplayName,  
         XGameSaveUpdateHandle* updateContext  
)  
```

### Parameters

*container*   \_In\_\
类型：XGameSaveContainerHandle

要更新的 XGameSaveContainer 的句柄。

*containerDisplayName*   \_In\_z\_\
类型：char\*

要更新的容器的显示名称。

*updateContext*   \_Outptr\_result\_nullonfailure\_\
类型：XGameSaveUpdateHandle\*

要创建的 XGameSaveUpdate 的句柄。

### Return value

类型：HRESULT

函数结果。

## Remarks

<Note>此函数在时间敏感型线程上调用是不安全的。有关详细信息，请参阅[时间敏感型线程](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)。</Note>

此 API 的存储部分旨在以安全、可靠和事务化的方式轻松地将数据从游戏传输到持久存储。我们希望确保容器的支持数据始终一致，因此我们希望整个操作以原子方式成功或失败。我们不希望发生部分更新，即某些 Blob 数据与容器中的其他数据不一致。为此，我们提供了一个更新上下文，可以将 Blob 写入和删除提交到该上下文，准备就绪后再提交整个上下文。实际操作如下：

**XGameSaveUpdate** 会被填充要在容器内 Blob 上执行的写入和删除操作，方法是通过 [XGameSaveSubmitBlobWrite](/reference/system/xgamesave/functions/xgamesavesubmitblobwrite) 和 [XGameSaveSubmitBlobDelete](/reference/system/xgamesave/functions/xgamesavesubmitblobdelete)。通过调用 [XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate) 来完成更新。

当你使用完 **XGameSaveUpdate** 后，请使用 [XGameSaveCloseUpdate](/reference/system/xgamesave/functions/xgamesavecloseupdate) 将其关闭。

以下 C++ 示例演示同步的 XGameSave 更新。

<a id="example" />

```cpp theme={null}
// SYNC Write - should not be called on a time sensitive thread 
//              as this will block until the operation is complete 
void Sample::_SaveDataSync(const char* containerName, const char* containerDisplayName) 
{ 
    HRESULT hr; 
    XGameSaveContainerHandle containerContext; 
    XGameSaveUpdateHandle updateContext; 
  
    hr = XGameSaveCreateContainer(_provider, containerName, &containerContext); 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateUpdate(containerContext, containerDisplayName, &updateContext); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "WorldState", _worldState.data(), _worldState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "PlayerState", _playerState.data(), _playerState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(updateContext, "PlayerInventory", _playerInventory.data(), _playerInventory.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        if (_clearLevelProgress) 
        { 
            hr = XGameSaveSubmitBlobDelete(updateContext, "LevelProgress"); 
        } 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitUpdate(updateContext); 
    } 
  
    if (updateContext) 
    { 
        XGameSaveCloseUpdate(updateContext); 
    } 
    if (containerContext) 
    { 
        XGameSaveCloseContainer(containerContext); 
    } 
  
    _HandleContainerUpdateErrors(hr); 
} 
  
  
void Sample::_HandleContainerUpdateErrors(HRESULT hr) 
{ 
    switch (hr) 
    { 
    case E_GS_INVALID_CONTAINER_NAME: 
        // tried to access a container with an invalid name 
        break; 
    case E_GS_OUT_OF_LOCAL_STORAGE: 
        // storage location is full, let the user know that saves won't work till this is fixed 
        break; 
    case E_GS_UPDATE_TOO_BIG: 
        // the blob that we provided was too big, can't be larger than GS_MAX_BLOB_SIZE 
        break; 
    case E_GS_QUOTA_EXCEEDED: 
        // the update we did was larger than our overall quota, need to track that! (see XGameSaveQueryRemainingQuota & XGameSaveQueryRemainingQuotaAsync) 
        break; 
    case E_GS_CONTAINER_NOT_IN_SYNC: 
    case E_GS_CONTAINER_SYNC_FAILED: 
        // need to sync and we are offline ? 
        break; 
    case E_GS_HANDLE_EXPIRED: 
        // need to re-initialize since another device has taken 
        // ownership while we were suspended and/or busy 
        break; 
    } 
}
```

以下 C++ 示例演示异步的 XGameSave 更新。

```cpp theme={null}
// ASYNC Write - can be kicked off from a time sensitive thread 
//               actual work and completion will be scheduled base upon 
//               the configuration of the async_queue tied to the XAsyncBlock. 
void Sample::_SaveDataAsync(const char* containerName, const char* containerDisplayName) 
{ 
    struct SaveContext 
    { 
        SaveContext(Sample* s) : self(s), containerContext(nullptr), updateContext(nullptr) {} 
        ~SaveContext() 
        { 
            if (updateContext) 
            { 
                XGameSaveCloseUpdate(updateContext); 
            } 
            if (containerContext) 
            { 
                XGameSaveCloseContainer(containerContext); 
            } 
        } 
  
        XAsyncBlock async; 
        XGameSaveContainerHandle containerContext; 
        XGameSaveUpdateHandle updateContext; 
        Sample* self; 
    }; 
  
    HRESULT hr; 
    SaveContext* saveContext = new SaveContext(this); 
    if (saveContext == nullptr) 
    { 
        hr = E_OUTOFMEMORY; 
    } 
    if (SUCCEEDED(hr)) 
    { 
        saveContext->async.context = saveContext; 
        saveContext->async.callback = [](XAsyncBlock* async) 
        { 
            auto ctx = reinterpret_cast<SaveContext*>(async->context); 
            auto self = ctx->self; 
            HRESULT hr = XGameSaveSubmitUpdateResult(async); 
            self->_HandleContainerUpdateErrors(hr); 
            delete ctx; 
        }; 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateContainer(_provider, containerName, &saveContext->containerContext); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveCreateUpdate(saveContext->containerContext, containerDisplayName, &saveContext->updateContext); 
    } 
  
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "WorldState", _worldState.data(), _worldState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "PlayerState", _playerState.data(), _playerState.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitBlobWrite(saveContext->updateContext, "PlayerInventory", _playerInventory.data(), _playerInventory.size()); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        if (_clearLevelProgress) 
        { 
            hr = XGameSaveSubmitBlobDelete(saveContext->updateContext, "LevelProgress"); 
        } 
    } 
    if (SUCCEEDED(hr)) 
    { 
        hr = XGameSaveSubmitUpdateAsync(saveContext->updateContext, &saveContext->async); 
    } 
    if (SUCCEEDED(hr)) 
    { 
        // context is now owned by the async 
        saveContext = nullptr; 
    } 
  
    // if there was any error we need to cleanup the saveContext 
    if (saveContext) 
    { 
        delete saveContext; 
    } 
  
} 
```

## Requirements

**头文件：** XGameSave.h

**库：** xgameruntime.lib

**受支持的平台：** Windows、XBOX One 系列主机和 XBOX Series 主机

## Conceptual documentation

* [时间敏感型线程](https://learn.microsoft.com/gaming/gdk/docs/gdk-dev/console-dev/overviews/threads/time-sensitive-threads)

## See also

[XGameSave](/reference/system/xgamesave/xgamesave_members)\
[XGameSaveSubmitBlobWrite](/reference/system/xgamesave/functions/xgamesavesubmitblobwrite)\
[XGameSaveSubmitBlobDelete](/reference/system/xgamesave/functions/xgamesavesubmitblobdelete)\
[XGameSaveSubmitUpdate](/reference/system/xgamesave/functions/xgamesavesubmitupdate)\
[XGameSaveCloseUpdate](/reference/system/xgamesave/functions/xgamesavecloseupdate)
[调试游戏保存](/build/core-features/common/game-save/game-saves-debugging)


## Related topics

- [XGameSaveCloseUpdate](/zh-CN/reference/system/xgamesave/functions/xgamesavecloseupdate.md)
- [XGameSaveSubmitUpdate](/zh-CN/reference/system/xgamesave/functions/xgamesavesubmitupdate.md)
- [XGameSaveSubmitUpdateAsync](/zh-CN/reference/system/xgamesave/functions/xgamesavesubmitupdateasync.md)
- [XGameSaveSubmitBlobDelete](/zh-CN/reference/system/xgamesave/functions/xgamesavesubmitblobdelete.md)
- [XGameSaveSubmitBlobWrite](/zh-CN/reference/system/xgamesave/functions/xgamesavesubmitblobwrite.md)
