Вызов Dispose() vs при выходе объекта за пределы области видимости / метода завершается

StackOverflow https://stackoverflow.com/questions/1832992

Вопрос

У меня есть метод, который имеет try/catch/finaly блок внутри.В блоке try я заявляю SqlDataReader следующим образом:

SqlDataReader aReader = null;          
aReader = aCommand.ExecuteReader();

В finally блок, объекты, которые удаляются вручную, - это те, которые заданы на уровне класса.Итак, объекты в методе, которые реализуют IDisposable, такие как SqlDataReader как указано выше, утилизируются ли они автоматически? Close() вызывается по aReader через некоторое время выполняется цикл для получения содержимого программы чтения (которое должно быть Dispose() как это называется Close()).Если нет вызова в Close(), будет ли этот объект закрыт / удален автоматически, когда метод завершится или объект выйдет за пределы области видимости?

Редактировать:Я осознаю, что using утверждение, но есть сценарии, которые меня сбивают с толку.

Это было полезно?

Решение

Нет, объекты не удаляются автоматически, когда они выходят за пределы области видимости.

Они даже не гарантированно будут утилизированы, если / когда они будут собраны как мусор, хотя многие IDisposable объекты реализуют "запасной" финализатор, чтобы гарантировать, что они в конечном итоге будут удалены.

Вы несете ответственность за обеспечение того, чтобы любой IDisposable предметы утилизируют, предпочтительно завернув их в using блок.

Другие советы

Вы должны использовать using {...} блок для обертывания ваших IDisposable объектов в - the Dispose() метод (который для SqlDataReader передается в Close() метод) будет вызван, когда закончится блок using.Если вы не используете using, объект будет нет будет автоматически удаляться, когда он выходит за пределы области видимости - это будет зависеть от средства завершения объекта, если оно у него есть, чтобы избавиться от ресурсов при сборе мусора

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // ... do stuff
}   // aReader.Dispose() called here

Шаблон Dispose не дает никаких гарантий относительно того, какие объекты будут вызывать Dispose для каких других объектов;иногда это может случиться, но вас это не должно волновать.Вместо этого вы несете ответственность за то, чтобы убедиться, что Dispose() вызывается для всех IDisposable объектов.Лучший способ сделать это - с помощью using заявление.Например:

using (SqlDataReader aReader = aCommand.ExecuteReader())
{
    // your code
}

Я согласен со всем вышесказанным.Тебе следует обязательно позвонить Dispose() самостоятельно, и самый простой способ добиться этого - с помощью using инструкция (вы также можете сделать это самостоятельно в finally блокировать - это более подробно, но иногда необходимо).Если вы этого не сделаете, вы можете обнаружить, что ваше приложение пропускает неуправляемые ресурсы, такие как дескрипторы или даже неуправляемую память, особенно если где-то под всем этим используются некоторые COM-компоненты или выполняются вызовы Win32 API.Очевидно, что это может привести к проблемам с производительностью и стабильностью, а также к чрезмерному использованию ресурсов.

Просто потому, что объекты, которые реализуют IDisposable "следует" реализовать финализатор, который вызывает их Dispose(bool disposing) метод освобождения неуправляемых ресурсов не является гарантией того, что это произойдет, поэтому вам определенно не следует полагаться на него.Смотрите, например, http://msdn.microsoft.com/en-us/library/b1yfkh5e%28VS.71%29.aspx для получения дополнительной информации по этому вопросу.

Кроме того, следует иметь в виду еще кое-что, что если в вашем типе есть элементы, которые являются одноразовыми, ваш тип должен либо реализовать IDisposable (если жизненный цикл этих элементов не управляется другим типом, что, очевидно, может привести к беспорядку), или, если вы используете такие элементы только в одном методе, или для реализации одной конкретной части функциональности, вам следует рассмотреть возможность создания для них локальных переменных / параметров в методах, которые их используют.

Я озадачен утверждением "В блоке finally объектами, которые удаляются вручную, являются те, которые установлены на уровне класса". Под объектами, установленными на уровне класса, вы подразумеваете поля?Вероятно, вам не следует избавляться от них в рамках обычного метода, потому что тогда время жизни полей непредсказуемо и зависит от того, какие методы вы случайно вызвали.Было бы лучше реализовать IDisposable и утилизировать поля в вашем методе Dispose.

Мог бы тот Используя заявление поможет?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top