问题
I have a .net core 3.1 console app.
I have a method with the following signature:
public async IAsyncEnumerable<string> GetFilePathsFromRelativePathAsync(string relativePath)
If I call it:
private async Task<IEnumerable<FileUpload>> GetFileUploadsAsync(string relativePath)
{
...
var filePaths = await service.GetFilePathsFromRelativePathAsync(relativePath);
...
}
I get the following error:
Error CS1061 'IAsyncEnumerable' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'IAsyncEnumerable' could be found (are you missing a using directive or an assembly reference?)
回答1:
The correct syntax is :
await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
{
....
}
An IAsyncEnumerable
is used to return a stream of elements that can be processed individually. That's why the feature is actually called async streams, causing quite a bit of confusion
Converting to Task< IEnumerable< FileUpload>>
The best solution would be to not convert, but change the signature to IEnumerable<FileUpload>
and return new FileUpload
instances as soon as they're created :
private async IAsyncEnumerable<FileUpload> GetFileUploadsAsync(string relativePath)
{
await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
{
var upload = new FileUpload(filePath);
yield return upload;
}
}
You can also gather all results, store them in a list and return them, eg with a ToListAsync
extension method :
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;
}
The best code is code you don't write though. The System.Linq.Async project provides LINQ operators for IAsyncEnumerable, including ToList.
The code is very simple but includes a few optimizations, like using ValueTask
instead of Task
and special treatment for data that comes from other operators like GroupBy and Reverse, that have to consume the entire IAsyncEnumerable
before producing their output.
来源:https://stackoverflow.com/questions/60148340/net-core-3-1-iasyncenumerablestring-does-not-contain-a-definition-for-get