IAsyncEnumerable 方法中的正确处置?
Correct disposal in IAsyncEnumerable methods?
答案可能是不可能,但问题是:假设您有一个 C# 方法来使用 TextReader
returns IAsyncEnumerable<string>
中的行。您如何确保在 IAsyncEnumerator<string>
上调用 DisposeAsync
时 TextReader
被处理掉?或者这是您需要编写自定义实现来实现的东西吗?
只需在异步迭代器中使用一个 try-finally 块,或者更简单地使用一个 using
块,一旦调用者完成枚举,TextReader
就会被释放。枚举是正常完成,还是由于异常或 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");
}
}
输出:
Line1
Line2
Line3
Disposed
答案可能是不可能,但问题是:假设您有一个 C# 方法来使用 TextReader
returns IAsyncEnumerable<string>
中的行。您如何确保在 IAsyncEnumerator<string>
上调用 DisposeAsync
时 TextReader
被处理掉?或者这是您需要编写自定义实现来实现的东西吗?
只需在异步迭代器中使用一个 try-finally 块,或者更简单地使用一个 using
块,一旦调用者完成枚举,TextReader
就会被释放。枚举是正常完成,还是由于异常或 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");
}
}
输出:
Line1
Line2
Line3
Disposed