Когда действительно Регистрирует. Бесплатные ресурсы ReadLines

При работе с файлами в C# я тренируюсь для размышления об освобождении связанных ресурсов. Обычно это - оператор использования, если это не один удобный метод лайнера как Файл. ReadAllLines, который откроет и закроет файл для меня.

.Net 4.0 представил Файл удобного метода. ReadLines. Это возвращает IEnumerable и тарифицировано как более эффективный способ обработать файл - он старается не хранить весь файл в памяти. Чтобы сделать это, которое я принимаю, существует некоторая задержанная логика выполнения в перечислителе.

Очевидно, так как этот метод возвращает IEnumerable, не и IDisposable, я не могу пойти со своей реакцией пищеварительного тракта оператора использования.

Мои вопросы: Принимая это во внимание, есть ли какие-либо глюки на освобождении ресурса с этим методом?

Вызов этого метода означают, что выпуск связанных блокировок файла недетерминирован?

13
задан David 31 July 2010 в 18:08
поделиться

2 ответа

IEnumerable не наследуется от IDisposable, потому что обычно класс, который его реализует, дает вам только обещание быть перечисляемым, на самом деле он ничего не сделал тем не менее, это требует утилизации.

Однако, когда вы перечисляете его, вы сначала получаете IEnumerator , вызывая метод IEnumerable.GetEnumerator , и обычно базовый объект, который вы возвращаете , делает реализовать IDisposable .

Способ реализации foreach аналогичен следующему:

var enumerator = enumerable.GetEnumerator();
try
{
    // enumerate
}
finally
{
    IDisposable disposable = enumerator as IDisposable;
    if (disposable != null)
        disposable.Dispose();
}

Таким образом, если объект действительно реализует IDisposable , он будет удален. Для File.ReadLines файл на самом деле не открывается, пока вы не начнете перечислять его, поэтому объект, который вы получаете из File.ReadLines , не нужно удалять, но вам нужно перечислить получить, делает.

Как указано в комментариях, IEnumerator не наследуется от IDisposable , хотя многие типичные реализации наследуют его, тогда как общий IEnumerator наследует IDisposable .

17
ответ дан 1 December 2019 в 22:22
поделиться

+1 за ответ Лассе.

В частности, для File.ReadLines , где перечислитель вызывает .MoveNext () , внутренний TextReader будет удален при обнаружении EOF или возникает неисправность.

private bool MoveNext()
{
    bool flag;
    try
    {
        switch (this.<>1__state)
        {
            case 0:
                this.<>1__state = -1;
                this.<>7__wrap2 = this.reader;
                this.<>1__state = 1;
                this.<line>5__1 = null;
                goto Label_005C;

            case 2:
                this.<>1__state = 1;
                goto Label_005C;

            default:
                goto Label_0078;
        }
    Label_003E:
        this.<>2__current = this.<line>5__1;
        this.<>1__state = 2;
        return true;
    Label_005C:
        if ((this.<line>5__1 = this.reader.ReadLine()) != null)
        {
            goto Label_003E;
        }
        this.<>m__Finally3(); // Disposal at end of file.
    Label_0078:
        flag = false;
    }
    fault
    {
        this.System.IDisposable.Dispose(); // Disposal due to fault.
    }
    return flag;
}
5
ответ дан 1 December 2019 в 22:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: