Правильное удаление в IAsyncEnumerable методах? - PullRequest
0 голосов
/ 11 октября 2019

Ответом может быть то, что это невозможно, но вопрос в следующем: предположим, у вас есть метод C # для использования строк в TextReader, который возвращает IAsyncEnumerable<string>. Как вы гарантируете, что когда DisposeAsync вызывается на IAsyncEnumerator<string>, что TextReader утилизируется? Или вам нужно написать собственную реализацию для достижения цели?

1 Ответ

2 голосов
/ 11 октября 2019

Просто используйте блок 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
Утилизировано

...