Search code examples
uwpc++-winrt

How to implement when_all for list of IAsyncOperation<TResult>


As in the title: How to implement a method similar to concurrency::when_all for list of IAsyncOperation?

Best regards, Michał


Solution

  • Based on this thread, you can define a when_all template manually. But it needs you to pass each task as a parameter.

    Update:

    If you want to put a vector of IAsyncAction in when_all method, you can refer to this thread. For example:

    MainPage.h

    template <typename T>
    Windows::Foundation::IAsyncAction when_each(T first, T last)
    {
        for (; first != last; ++first)
        {
            co_await *first;
        }
    }
    
    struct MainPage : MainPageT<MainPage>
    {
        MainPage();
    
        Windows::Foundation::IAsyncAction wait_for(Windows::Foundation::TimeSpan duration);
    
        Windows::Foundation::IAsyncAction ClickHandler(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& args);
    };
    

    MainPage.cpp:

    #include <debugapi.h>
    
    using namespace winrt;
    using namespace Windows::UI::Xaml;
    using namespace std::chrono;
    
    Windows::Foundation::IAsyncAction MainPage::wait_for(Windows::Foundation::TimeSpan duration)
    {
        co_await duration;
        hstring formattedText = L"done" + to_hstring(duration.count());
        OutputDebugString(formattedText.c_str());
    }
    
    Windows::Foundation::IAsyncAction MainPage::ClickHandler(IInspectable const&, RoutedEventArgs const&)
    {
        std::vector v{ wait_for(4s), wait_for(2s), wait_for(3s) };
        co_await when_each(v.begin(), v.end());
    }
    

    The result of output:

    done 20000000 done 30000000​ done 40000000

    Then you can replace wait_for method with your async operations to achieve it.