将 IAsyncEnumable 转换为 List

所以在 C # 8中我们得到了 IAsyncEnumerable接口的加入。

如果我们有一个正常的 IEnumerable,我们可以作出一个 List或几乎任何其他集合,我们想出来。多亏了 Linq。

var range = Enumerable.Range(0, 100);
var list = range.ToList();

现在我想把我的 IAsyncEnumerable转换成 List这当然是异步的。那个案例已经有 Linq 实现了吗?如果没有,我怎么能自己转换呢?

47613 次浏览

Sure - you just need the ToListAsync() method, which is in the System.Linq.Async NuGet package. Here's a complete example:

Project file:

<Project Sdk="Microsoft.NET.Sdk">


<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="System.Linq.Async" Version="4.0.0" />
</ItemGroup>


</Project>

Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;


class Program
{
static async Task Main(string[] args)
{
IAsyncEnumerable<string> sequence = GetStringsAsync();
List<string> list = await sequence.ToListAsync();
Console.WriteLine(list.Count);
}


static async IAsyncEnumerable<string> GetStringsAsync()
{
yield return "first";
await Task.Delay(1000);
yield return "second";
await Task.Delay(1000);
yield return "third";
}
}

On the off chance that you don't want to to bring in a NuGet package, here is (probably something similar to) the extension method mentioned in the package:

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