How to co_await in a function that returns IAsyncAction?

936 views Asked by At

Here's a simple function that reads a file into a textbox:

IAsyncAction MainPage::OnOpenAppBarButtonClick(IInspectable const& /*sender*/, RoutedEventArgs const& /*args*/)
{
    FileOpenPicker picker{};
    picker.FileTypeFilter().Append(L".txt");

    StorageFile storageFile = co_await picker.PickSingleFileAsync();

    if (storageFile)
    {
        txtbox().Text(co_await FileIO::ReadTextAsync(storageFile));
    }
}

This used to work fine. As I understand, the return type is IAsyncAction when we don't really return a value from a coroutine. Today I updated the WinRT plugin, and now it fails with an error:

error C3773: Use of 'co_await' in this context is a non-conforming extension in C++20

And asks me to use /await to compile the code. It does compile and run fine with that compiler switch, but what is non-conforming about the code above and what's the conforming way of writing this function?

Microsoft has a very similar example in their documentation:

#include <iostream>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Web.Syndication.h>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Syndication;

void PrintFeed(SyndicationFeed const& syndicationFeed)
{
    for (SyndicationItem const& syndicationItem : syndicationFeed.Items())
    {
        std::wcout << syndicationItem.Title().Text().c_str() << std::endl;
    }
}

IAsyncAction ProcessFeedAsync()
{
    Uri rssFeedUri{ L"https://blogs.windows.com/feed" };
    SyndicationClient syndicationClient;
    SyndicationFeed syndicationFeed{ co_await syndicationClient.RetrieveFeedAsync(rssFeedUri) };
    PrintFeed(syndicationFeed);
}

int main()
{
    winrt::init_apartment();

    auto processOp{ ProcessFeedAsync() };
    // do other work while the feed is being printed.
    processOp.get(); // no more work to do; call get() so that we see the printout before the application exits.
}

This fails to compile with the same error with /std:c++latest (C++20).

The main question is how to write the first example function in a conforming manner.

0

There are 0 answers