本主题提供了通用异步任务包装器的示例。 与其手动设置异步块并为每个任务调用 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;
});
}
上述示例实现了一个函数,该函数接受一个异步块和两个回调:一个工作和一个完成。 由于完成回调是可选的,因此可以编写一个只接受工作回调的版本。
它使用标准模式设置异步块、设置上下文数据并调用 XAsyncRun。
RunTask
封装样本代码,创建简单的独立任务函数。 简单的数据捕获通过使用 std::function
传递给回调,而不需要上下文参数。
RunTask(taskQueue,
[]()
{
// Work Callback
},
[]()
{
// Completion Callback
});