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

# Generic async task wrapper

> Generic async task wrapper

This topic provides an example of a generic async task wrapper. Instead of manually setting up async blocks and calling [XAsyncRun](/reference/system/xasync/functions/xasyncrun)
for each task, create a `RunTask` wrapper to simplify this
process. By using this wrapper, you can specific a task queue, a work, and an optional completion callback.

```c++ theme={null}
void RunTask(XTaskQueueHandle taskQueue,
    std::function<void()> workCallback,
    std::function<void()> completionCallback)
{
    struct RunTaskContext
    {
        std::function<void()> workCallback;
        std::function<void()> completionCallback;
    };

    RunTaskContext* context = new RunTaskContext();
    context->workCallback = workCallback;
    context->completionCallback = completionCallback;
    XAsyncBlock* async = new XAsyncBlock{};
    async->queue = taskQueue;
    async->context = context;
    async->callback = [](XAsyncBlock* async)
    {
        RunTaskContext* context = static_cast<RunTaskContext*>(async->context);
        context->completionCallback();
        delete context;
        delete async;
    };

    // Callback passed to XAsyncRun is the work callback
    XAsyncRun(async,
        [](XAsyncBlock* async)->HRESULT
        {
            RunTaskContext* context = static_cast<RunTaskContext*>(async->context);
            context->workCallback();
            return S_OK;
        });
}
```

The previous sample implements a function that takes an async block and two
callbacks: one work and one completion. You can write a version to
just take a work callback, because the completion callback is optional.

It uses the standard pattern to setup an async block, setup context
data, and call [XAsyncRun](/reference/system/xasync/functions/xasyncrun). `RunTask` encapsulates the boilerplate
code, creating a simple standalone task function. Simple data capturing passes to the callbacks without context parameters by using `std::function`.

```c++ theme={null}
RunTask(taskQueue,
    []()
    {
        // Work Callback
    },
    []()
    {
        // Completion Callback
    });
```

## Reference API documentation

* [Xasync (API contents)](/reference/system/xasync/xasync_members)
  * Functions
    * [XAsyncRun](/reference/system/xasync/functions/xasyncrun)
* [Xtaskqueue (API contents)](/reference/system/xtaskqueue/xtaskqueue_members)

## See also

[Asynchronous programming overview](/build/core-features/common/async/async-toc)
[XAsync](/reference/system/xasync/xasync_members)
[XTaskQueue](/reference/system/xtaskqueue/xtaskqueue_members)


## Related topics

- [Async programming model in the XBOX GDK](/build/core-features/common/async/index.md)
- [XAsyncRun](/reference/system/xasync/functions/xasyncrun.md)
- [Asynchronous Programming Overview](/build/core-features/common/async/async-toc.md)
- [Unity C# API wrappers for the GDK](/build/gdk-and-engines/unity/unity-api-wrappers.md)
- [Multiplayer tasks](/services/xbox-services/multiplayer/mpsd/how-to/live-mpsd-how-tos.md)
