. net core 3.1: «IAsyncEnumerable <string>» не содержит определения «GetAwaiter» - PullRequest
1 голос
/ 10 февраля 2020

У меня есть консольное приложение. net core 3.1.

У меня есть метод со следующей подписью:

public async IAsyncEnumerable<string> GetFilePathsFromRelativePathAsync(string relativePath)

Если я его назову:

private async Task<IEnumerable<FileUpload>> GetFileUploadsAsync(string relativePath)
{
...
    var filePaths = await service.GetFilePathsFromRelativePathAsync(relativePath);
...
}

Я получаю следующую ошибку:

Ошибка CS1061 «IAsyncEnumerable» не содержит определения для «GetAwaiter», и доступный метод расширения «GetAwaiter», принимающий первый аргумент типа «IAsyncEnumerable», не может быть найденным (вам не хватает директивы using или ссылки на сборку?)

1 Ответ

2 голосов
/ 10 февраля 2020

Правильный синтаксис:

await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
{
    ....
}

IAsyncEnumerable используется для возврата потока элементов, которые могут обрабатываться индивидуально. Вот почему эта функция на самом деле называется asyn c streams , что вызывает путаницу

Преобразование в задачу >

Лучшим решением было бы не преобразовать, но изменить подпись на IEnumerable<FileUpload> и вернуть новые FileUpload экземпляры, как только они будут созданы:

private async IAsyncEnumerable<FileUpload> GetFileUploadsAsync(string relativePath)
{
    await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
    {
        var upload = new FileUpload(filePath);
        yield return upload;
    }
}

You Можно также собрать все результаты, сохранить их в списке и вернуть их, например, с помощью метода расширения ToListAsync:

public static async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source, CancellationToken cancellationToken=default)
{
    var list=new List<T>();
    await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
    {
        list.Add(item);
    }

    return list;
}

Лучший код - это код, который вы не пишете. Проект System.Linq.Asyn c предоставляет операторы LINQ для IAsyncEnumerable, включая ToList .

Код очень прост, но включает в себя несколько оптимизаций, например, использование ValueTask вместо Task и специальную обработку данных, поступающих от других операторов, таких как GroupBy и Reverse, которые должны потреблять все IAsyncEnumerable прежде чем производить свою продукцию.

...