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

# XUserSignOutAsync

> Asynchronously signs out a user on runtimes where the game manages sign-out.

# XUserSignOutAsync

Asynchronously signs out a user on runtimes where the game manages sign-out, such as Steam Deck.

## Syntax

```cpp theme={null}
HRESULT XUserSignOutAsync(
         XUserHandle user,
         XAsyncBlock* async
) noexcept
```

### Parameters

*user*   \_In\_\
Type: XUserHandle

A handle to the user to sign out.

*async*   \_Inout\_\
Type: [XAsyncBlock\*](https://docs.xbox.com/reference/system/xasync/structs/xasyncblock.md)

An [XAsyncBlock](https://docs.xbox.com/reference/system/xasync/structs/xasyncblock.md) for polling for the call's status and retrieving call results.

### Return value

Type: HRESULT

HRESULT success or error code. A success code means that the sign-out operation started, not that it finished. Call [XUserSignOutResult](https://docs.xbox.com/reference/system/xuser/functions/xusersignoutresult.md) to get the result of the operation.

| Return code | Description |
| - | - |
| S\_OK | The sign-out operation started. |
| E\_GAMERUNTIME\_INVALID\_HANDLE | The user handle isn't valid for the current Gaming Runtime session. |

For a list of error codes, see [Error codes](https://docs.xbox.com/reference/errorcodes.md).

## Remarks

**XUserSignOutAsync** starts an asynchronous operation that signs out *user*. Call [XUserSignOutResult](https://docs.xbox.com/reference/system/xuser/functions/xusersignoutresult.md) in the completion callback of *async* to get the result.

Call [XUserIsSignOutPresent](https://docs.xbox.com/reference/system/xuser/functions/xuserissignoutpresent.md) first, and call **XUserSignOutAsync** only when it returns `true`. When **XUserIsSignOutPresent** returns `false`, sign-out isn't available through this API in the current runtime.

When the user transitions to signed out, callbacks that you registered with [XUserRegisterForChangeEvent](https://docs.xbox.com/reference/system/xuser/functions/xuserregisterforchangeevent.md) receive the `SigningOut` and `SignedOut` [XUserChangeEvent](https://docs.xbox.com/reference/system/xuser/enums/xuserchangeevent.md) notifications. These notifications report an actual state transition. They aren't guaranteed for every call to **XUserSignOutAsync**, for example when the user is already signed out.

A failed or canceled operation doesn't tell you the user's current state. Handle and report the result code, and use [XUserGetState](https://docs.xbox.com/reference/system/xuser/functions/xusergetstate.md) and user change events to decide how your game treats the user afterward. A canceled operation returns `E_ABORT` from **XUserSignOutResult**.

Close each user handle that you acquire just once, when you no longer need it, by calling [XUserCloseHandle](https://docs.xbox.com/reference/system/xuser/functions/xuserclosehandle.md). You can keep a handle after the user signs out. If the same user signs in again, your change event callback receives `XUserChangeEvent::SignedInAgain` for that user.

The following example signs out a user. It requires `XUser.h`, `XAsync.h`, and `<memory>`. It assumes that the game created *queue* by calling [XTaskQueueCreate](https://docs.xbox.com/reference/system/xtaskqueue/functions/xtaskqueuecreate.md) and dispatches the queue's completion port so that the completion callback runs.

```cpp theme={null}
HRESULT SignOutUser(XUserHandle user, XTaskQueueHandle queue)
{
    if (!XUserIsSignOutPresent())
    {
        // Sign-out is unavailable through this API.
        return S_FALSE;
    }

    auto async = std::make_unique<XAsyncBlock>();
    async->queue = queue;
    async->callback = [](XAsyncBlock* ab)
    {
        std::unique_ptr<XAsyncBlock> owned{ ab };
        HRESULT hr = XUserSignOutResult(ab);
        if (FAILED(hr))
        {
            // Report hr. Use XUserGetState and user change events,
            // not this result, to decide how to treat the user.
        }
    };

    HRESULT hr = XUserSignOutAsync(user, async.get());
    if (SUCCEEDED(hr))
    {
        // The completion callback now owns the XAsyncBlock.
        async.release();
    }
    return hr;
}
```

## Requirements

**Header:** XUser.h

**Library:** xgameruntime.lib

**Supported platforms:** Windows, Steam Deck, XBOX One family consoles and XBOX Series consoles. To check whether sign-out is available at run time, call [XUserIsSignOutPresent](https://docs.xbox.com/reference/system/xuser/functions/xuserissignoutpresent.md).

## See also

[XUser](https://docs.xbox.com/reference/system/xuser/xuser_members.md)

[XUserIsSignOutPresent](https://docs.xbox.com/reference/system/xuser/functions/xuserissignoutpresent.md)

[XUserSignOutResult](https://docs.xbox.com/reference/system/xuser/functions/xusersignoutresult.md)

[XUserRegisterForChangeEvent](https://docs.xbox.com/reference/system/xuser/functions/xuserregisterforchangeevent.md)

[XUser cross-platform support](https://docs.xbox.com/build/core-features/common/user/xuser-crossplatform.md)


## Related topics

- [XUserSignOutResult](https://docs.xbox.com/reference/system/xuser/functions/xusersignoutresult.md)
- [XUserIsSignOutPresent](https://docs.xbox.com/reference/system/xuser/functions/xuserissignoutpresent.md)
- [XUser Cross-Platform Support](https://docs.xbox.com/build/core-features/common/user/xuser-crossplatform.md)
- [XUser (API contents)](https://docs.xbox.com/reference/system/xuser/xuser_members.md)
- [XUserGetSignOutDeferral](https://docs.xbox.com/reference/system/xuser/functions/xusergetsignoutdeferral.md)
