122

So in C#8 we got the addition of the IAsyncEnumerable interface.

If we have a normal IEnumerable we can make a List or pretty much any other collection we want out of it. Thanks to Linq there.

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

Well now I want to convert my IAsyncEnumerable to a List and this of course asynchronously. Are there already Linq implementations for that case? If there isn't, how could I convert it myself then?

2 Answers 2

194

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";
    }
}
11
  • 4
    Thanks for that one, interesting that it isn't part of the .Net Core 3.1 Framework yet.
    – Twenty
    Commented Dec 17, 2019 at 19:07
  • 6
    @Twenty: As a separate package, it's easily usable on platforms stretching way back.
    – Jon Skeet
    Commented Dec 17, 2019 at 19:20
  • 2
    @ca9163d9: "It gets the error" doesn't really provide much information. I suggest you ask a new question with a complete minimal reproducible example.
    – Jon Skeet
    Commented Feb 12, 2020 at 22:08
  • 2
    @ca9163d9: As I said before, please ask a new question with a complete example - and please make the error clearer than "it failed".
    – Jon Skeet
    Commented Apr 11, 2020 at 5:46
  • 1
    @db2: Yes, it is - you'd need to be more specific about the problems for me to be able to help. I suggest you ask a new question with a minimal reproducible example.
    – Jon Skeet
    Commented Jun 14, 2021 at 18:01
30

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;
    }
}
7
  • 3
    github.com/dotnet/reactive/blob/…
    – Ian Kemp
    Commented Nov 2, 2020 at 11:17
  • Just curious - does anyone know why the source linked by Ian Kemp defines the main implementation in a static local function 'Core' and then calls it directly, instead of just implementing it inline? Commented Jan 10, 2021 at 20:59
  • 4
    @Andrew Williamson that's been changed in a recent commit. The reason will be for performance. It now does some validation of the parameters. You'll notice the outer function isn't marked async, only the local function is. So now if the validation fails we will not have gone to all the trouble of setting up the async state machine. Commented Jan 12, 2021 at 7:20
  • Why wouldn't you want to use the nuget package? It's not one of those "shady" packages but one supported by the dotnetfoundation. Commented Apr 29, 2021 at 11:51
  • 6
    @JonasStensved because it may cause clashes, if it's used together with EF Core for example. I use the ToListAsync just once in my code until now, and if I add the Nuget package, I get a lot of ambiguous errors because EF Core is a dependency in the same project.
    – El Mac
    Commented Jun 17, 2021 at 11:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.