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:
- Perform all async operations at start
- Use
IEnumerable<Task<T>>
rather thanIEnumerable<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);
}