Правильная утилизация в методах IAsyncEnumerable?
Ответ на этот вопрос может заключаться в том, что это невозможно, но вопрос в следующем: предположим, что у вас есть метод C# для использования строк в TextReader
что возвращается IAsyncEnumerable<string>
. Как вы гарантируете, что когдаDisposeAsync
называется на IAsyncEnumerator<string>
что TextReader
утилизируется? Или для этого вам нужно написать собственную реализацию?
1 ответ
Решение
Просто используйте блок 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");
}
}
Выход:
Строка1
Строка2
Строка3
Удалено