Skip to content

Async streams C# 8.0new scenarios

Create and consume streams asynchronously.

Prior to C# 8 IEnumerable and yield did not play well with Task and await.

This meant that you could only foreach over items you had to either forgo async or:

  1. Perform all async operations at start
  2. Use IEnumerable<Task<T>> rather than IEnumerable<T> and await each result

C# 8 allows a new await foreach syntax that paired with yield return await hides this complexity.

Code

C#
await foreach (var contents in GetTextFileContentsStream("c:\\textfiles))
    Console.WriteLine(contents);

async IAsyncEnumerable<string> GetTextFileContentsStream(string path)
{
    foreach (var file in Directory.GetFiles(path))
        yield return await File.ReadAllTextAsync(file);
}
C#
foreach (var contents in await GetFileContents("c:\\textfiles"))
    Console.WriteLine(contents);

async Task<IEnumerable<string>> GetFileContents(string path)
{
    var allContents = new List<string>();
    foreach (var file in Directory.GetFiles(path))
        allContents.Add(await File.ReadAllTextAsync(file));
    return allContents;
}
C#
foreach (var contents in await GetFileContents("c:\\textfiles"))
    Console.WriteLine(contents);

IEnumerable<Task<string>> GetFileContents(string path)
{
    foreach (var file in Directory.GetFiles(path))
        yield return File.ReadAllTextAsync(file);
}

More information