Is there an equivalent to JavaScript's Promise.all
in C++ or C++/WinRT for awaitables (or just Windows.Foundation.IAsyncAction
)?
For example, I am trying to gather multiple IAsyncActions and continue when all of them have completed. For now I'm starting each action and then awaiting them one by one in a simple loop:
winrt::IAsyncAction AwaitMultiple(std::vector<winrt::IAsyncAction> actions)
{
for (const auto& action : actions)
{
co_await action;
}
}
// ... somewhere else...
winrt::IAsyncAction MyFunctionAsync()
{
std::vector<winrt::IAsyncAction> actions{};
actions.push_back(/* some function that generates an IAsyncAction */);
actions.push_back(/* some function that generates an IAsyncAction */);
actions.push_back(/* some function that generates an IAsyncAction */);
// ... etc...
co_await AwaitMultiple(actions);
// ... do other stuff...
}
Is there a better way to do this? Is there a language way?
Disclaimer: I work for Microsoft.
As is often the case, there is indeed a C++/WinRT function for almost this case: winrt::when_all(T... async)
(it is not currently documented on Advanced concurrency and asynchrony with C++/WinRT).
If you have modern C++/WinRT, you can await multiple actions at once:
winrt::IAsyncAction MyFunctionAsync()
{
const auto myAction = /* function that generates an IAsyncAction */;
const auto myAction2 = /* function that generates an IAsyncAction */;
const auto myAction3 = /* function that generates an IAsyncAction */;
// magic!
co_await winrt::when_all(myAction, myAction2, myAction3);
}
This is similar to the Parallel Pattern Library (PPL) when_all
.
This doesn't solve the std::vector<winrt::IAsyncAction>
above, but luckily Raymond Chen has some posts about that:
A customer wanted to know how they could pass a std::vector of IAsyncAction objects to the when_all function.
std::vector<IAsyncAction> actions = get_actions(); for (auto&& action : actions) co_await action;
[... some more content about trying to wrap that in an overload for
winrt::when_all
...]
Synthesizing a when_all coroutine from pieces you already have
See also: