The answer to this may be that it's not possible, but the question is: assume you have a C# method for consuming the lines in a TextReader
that returns IAsyncEnumerable<string>
. How do you ensure that when DisposeAsync
is called on the IAsyncEnumerator<string>
that the TextReader
is disposed of? Or is this something you need to write a custom implementation to achieve?
Just use a try
-finally
block inside the async iterator, or more simply a using
block, and the TextReader
will be disposed as soon as the caller completes the enumeration. It doesn't matter if the enumeration will complete normally, or prematurely because of an exception or a break
.
static async Task Main(string[] args)
{
await foreach (var line in GetLines())
{
Console.WriteLine(line);
}
}
private static async IAsyncEnumerable<string> GetLines()
{
var reader = new StringReader("Line1\nLine2\nLine3");
try
{
while (true)
{
var line = await reader.ReadLineAsync();
if (line == null) break;
yield return line;
}
}
finally
{
reader.Dispose();
Console.WriteLine("Disposed");
}
}
Output:
Line1
Line2
Line3
Disposed