Мы используем Enterprise Library 3.0 для доступа к Oracle DB (клиент microsoft oracle). Что происходит, когда я не размещаю экземпляр DbCommand после вызова хранимой процедуры или функции? Автоматически ли сборщик .NET собирает их? Обратите внимание, что мы действительно следим за тем, чтобы транзакция/соединение закрывались и располагались правильно.
Необходимо ли использовать DbCommand после использования?
Ответ 1
Это дубликат, но у меня нет времени, чтобы найти оригинал.
Если он реализует IDisposable, и если вы его создали, вам нужно вызвать Dispose на нем. Именно поэтому разработчик класса сделал его реализацией IDisposable.
Сборщик мусора не вызывает Dispose во всех объектах, реализующих IDisposable.
Ответ 2
Отражатель не указывает, что OracleCommand
, в частности, переопределяет Dispose (от реализации System.ComponentModel.Component
, так или иначе), поэтому, скорее всего, это не повредит вашему приложению, если вы его не назовете.
Важно, однако, что OracleCommand
специально реализует IDbCommand
, который специально реализует IDisposable
. Если вы заменили OracleCommand
на другой IDbCommand
, то скорее всего вы захотите использовать Dispose()
. И хотя SqlCommand
явно не переопределяет Dispose()
, Odbc и OleDb, безусловно, делают.
Короче говоря, поскольку он IDisposable
, вы должны распоряжаться им, просто чтобы быть в безопасности.
Ответ 3
Из документации для IDisposable
:
Основное использование этого интерфейса - освобождение неуправляемых ресурсов. Сборщик мусора автоматически освобождает память, выделенную управляемому объекту, когда этот объект больше не используется. Однако предсказать, когда произойдет сбор мусора, невозможно. Кроме того, сборщик мусора не знает о неуправляемых ресурсах, таких как дескрипторы окон или открытые файлы и потоки.
Используйте метод Dispose этого интерфейса для явного освобождения неуправляемых ресурсов в сочетании с сборщиком мусора. Потребитель объекта может вызвать этот метод, когда объект больше не нужен.
Учитывая это, объект, реализующий IDisposable
, потенциально поддерживает ссылки на неуправляемые ресурсы. Эти ресурсы не освобождаются до тех пор, пока сборщик мусора не появится и не соберет объект. Однако, поскольку вы не можете знать, когда сборщик мусора сделает это, одноразовые объекты (например, OracleDbCommand
) могут зависнуть намного дольше, чем вы могли бы захотеть.
Если объект реализует IDisposable
, вы должны как можно скорее вызвать его, чтобы освободить неуправляемые ресурсы, на которые он ссылается. Это может быть достигнуто либо прямым вызовом Dispose
, либо объявлением его в используемом блоке.
Ответ 4
Не уверенно на 100% об Oracle, но при использовании SqlCommand он должен быть удален после использования. Вы можете либо просто вызвать .Dispose(), либо просто поместить его в используемый блок, например:
using(DbCommand cmd = new DbCommand(foo, bar))
{
// use cmd object
}