通用异步任务包装器

本主题提供了通用异步任务包装器的示例。 与其手动设置异步块并为每个任务调用 XAsyncRun,不如创建 RunTask 包装器来简化此过程。 通过使用这个包装器,您可以指定任务队列、工作和可选完成回调。

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;
        });
}

上述示例实现了一个函数,该函数接受一个异步块和两个回调:一个工作和一个完成。 由于完成回调是可选的,因此可以编写一个只接受工作回调的版本。

它使用标准模式设置异步块、设置上下文数据并调用 XAsyncRunRunTask 封装样本代码,创建简单的独立任务函数。 简单的数据捕获通过使用 std::function 传递给回调,而不需要上下文参数。

RunTask(taskQueue,
    []()
    {
        // Work Callback
    },
    []()
    {
        // Completion Callback
    });

另请参阅

异步编程概述
XAsync
XTaskQueue