Как co_await в функции, которая возвращает IAsyncAction?

#c #windows-runtime #coroutine #c 20 #c -winrt

#c #windows-среда выполнения #сопрограмма #c 20 #c -winrt #c #c -winrt

Вопрос:

Вот простая функция, которая считывает файл в текстовое поле:

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

    StorageFile storageFile = co_await picker.PickSingleFileAsync();

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

Раньше это работало нормально. Насколько я понимаю, возвращаемый тип — это IAsyncAction когда мы на самом деле не возвращаем значение из сопрограммы. Сегодня я обновил плагин WinRT, и теперь он выдает ошибку:

ошибка C3773: использование ‘co_await’ в этом контексте является несоответствующим расширением в C 20

И просит меня использовать /await для компиляции кода. Он действительно компилируется и работает нормально с этим переключателем компилятора, но что не соответствует приведенному выше коду и каков соответствующий способ написания этой функции?

У Microsoft есть очень похожий пример в их документации:

 #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 constamp; syndicationFeed)
{
    for (SyndicationItem constamp; 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.
}
  

Это не удается скомпилировать с той же ошибкой /std:c latest , что и (C 20).

Главный вопрос заключается в том, как написать первый пример функции соответствующим образом.

Комментарии:

1. Я заметил, что ваша функция не имеет ни a return ...; , ни a co_return; . Я не знаю, исправляет ли это, но лучше ничего не возвращать.

2. @chris вы не можете co_return использовать функцию, которая возвращает IAsyncAction , поскольку это цель этого типа. Если вы добавляете co_return {}; оператор, компилятор жалуется, что «не имеет члена return_type «. Вы можете добавлять co_return; , но это все равно, что добавлять return; в конец функции, которая возвращает void . Я не думаю, что синтаксически допустимо добавлять регулярное return в сопрограмму.

3. Неважно, я тупой и ужасно плохо помню, как C справляется с этим.

4. Похоже, по этому поводу возникла проблема , но она была закрыта, поскольку «требуется дополнительная информация». Может быть, вы можете добавить недостающую информацию и исправить эту проблему?

5. @RaymondChen Я добавил полный пример из документации Microsoft, который также не может быть скомпилирован под C 20.