将 IAsyncEnumerable 转换为列表

Twe*_*nty 45 c# linq ienumerable c#-8.0 iasyncenumerable

所以在 C#8 中我们添加了IAsyncEnumerable接口。

如果我们有一个法线,IEnumerable我们可以用它制作一个List或几乎任何其他我们想要的集合。感谢那里的 Linq。

var range = Enumerable.Range(0, 100);
var list = range.ToList();
Run Code Online (Sandbox Code Playgroud)

那么现在我想将 my 转换IAsyncEnumerable为 aList并且这当然是异步的。是否已经有针对这种情况的 Linq 实现?如果没有,我怎么能自己转换呢?

Jon*_*eet 79

当然-你只需要ToListAsync()方法,这是在System.Linq.AsyncNuGet包。这是一个完整的例子:

项目文件:

<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>
Run Code Online (Sandbox Code Playgroud)

代码:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Twenty:作为一个单独的包,它可以很容易地在历史悠久的平台上使用。 (5认同)
  • 感谢您的帮助,有趣的是它还不是 .Net Core 3.1 框架的一部分。 (3认同)
  • @ca9163d9:“它收到错误”并没有真正提供太多信息。我建议你用完整的 [mcve] 提出一个新问题。 (2认同)
  • @ca9163d9:正如我之前所说,请用完整的示例提出一个新问题 - 并且请使错误比“失败”更清楚。 (2认同)

Jam*_*lls 9

如果您不想引入 NuGet 包,这里是(可能类似于)包中提到的扩展方法:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @JonasStensved,因为如果它与 EF Core 一起使用,它可能会导致冲突。到目前为止,我在代码中只使用了一次“ToListAsync”,如果添加 Nuget 包,我会收到很多不明确的错误,因为 EF Core 是同一项目中的依赖项。 (6认同)
  • @Andrew Williamson 这在最近的提交中发生了变化。原因是为了性能。它现在对参数进行一些验证。您会注意到外部函数没有标记为异步,只有本地函数被标记为异步。因此,如果验证失败,我们将不必费尽心思去设置异步状态机。 (4认同)
  • https://github.com/dotnet/reactive/blob/7fe854ff18e8bbf2548bc18cd1dd5019a923e34a/Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ToList.cs#L32 (3认同)