Вопрос по .net, c# – Нужно ли утилизировать DbCommand после использования?

12

Мы используем Enterprise Library 3.0 для доступа к базе данных Oracle (клиент Microsoft Oracle). Что происходит, когда я не располагаю экземпляром DbCommand после вызова хранимой процедуры или функции? .NET автоматически собирает их? Обратите внимание, что мы уверены, что транзакция / соединение закрываются и удаляются должным образом.

Ваш Ответ

4   ответа
18

Если он реализует IDisposable, и если вы его создали, то вам нужно вызвать Dispose для него. Вот почему разработчик класса заставил его реализовать IDisposable.

Сборщик мусора не вызывает Dispose для всех объектов, реализующих IDisposable.

Не все пользователи IDisposable реализуют финализатор. Не все, кто проводит финализатор, будут следовать стандартной схеме. Вы не можете зависеть от существования финализатора, и не можете зависеть от вызова Dispose сборщиком мусора. John Saunders
@ RandomEngy - эта статья подразумевает, что Dispose () будет вызываться в финализаторе, только если финализатор вызывает Dispose (). Поскольку вы не можете быть уверены, что любой класс вызывает Dispose в финализаторе, вы должны усердно вызывать его самостоятельно. Jeremy Frey
Да, если вы считаете, что используемый вами класс неправильно реализует IDisposable, вы можете вызвать Dispose самостоятельно, просто чтобы быть в безопасности. Но говорить о том, что разработчик сделал класс IDisposable только потому, что они хотят, чтобы вы вызывали dispose для него, неверно. RandomEngy
@ RandomEngy: это не то, о чем вы спорили раньше. Либо сборщик мусора всегда будет вызывать Dispose, либо нет. Ты передумал? Это ваш новый аргумент? Если так, то, пожалуйста, добавьте ответ, ясно показывающий пример того, когда лучше игнорировать эту четкую передовую практику. Почему это лучше, чем простой вызов Dispose или реализация блока using? John Saunders
@ RandomEngy: если код неправильный, значит, он не чище. Извини, чувак, это просто опасно. Когда в коде, который «работал», начинают происходить странные вещи, первое, что я ищу, - это неправильное использование Dispose, а затем неправильная обработка исключений. Вы даете Мерфи отверстие, которое вам не нужно. John Saunders
7

OracleCommand специально переопределяет Dispose (изSystem.ComponentModel.Component любом случае, это реализация @), так что, скорее всего, это не повредит вашему приложению, если вы его не называете.

Важно то, чтоOracleCommand специально реализуетIDbCommand, который конкретно реализуетIDisposable. Если вы когда-нибудь заменили свойOracleCommand с другимIDbCommand, тогда вы, скорее всего, захотите использоватьDispose(). И покаSqlCommand явно не отменяетDispose(), Odbc и OleDb, безусловно, делают.

Короче говоря, так как этоIDisposable, ты должен избавиться от него, просто чтобы быть в безопасности.

4

IDisposable:

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

Используйте метод Dispose этого интерфейса, чтобы явно освобождать неуправляемые ресурсы вместе с сборщиком мусора. Потребитель объекта может вызвать этот метод, когда объект больше не нужен.

Дай это, объект, который реализуетIDisposable потенциально поддерживает ссылки на Неуправляемый Ресурсы. Эти ресурсы не освобождаются, пока не появится сборщик мусора и не соберет объект. Однако, так как вы не можете знать, когда сборщик мусора сделает это, одноразовые объекты (такие какOracleDbCommand) может зависать гораздо дольше, чем вы бы этого хотели.

Если объект реализуетIDisposable, тыдолже позвоните ему как можно скорее, чтобы освободить неуправляемые ресурсы, на которые он ссылается. Это можно сделать, вызвавDispose напрямую или объявив его в блоке использования.

Я прочитал это, чтобы сказать, что «Кроме того, сборщик мусора не знает о неуправляемых ресурсах, таких как дескрипторы окон или открытые файлы и потоки». Таким образом, GC будетн выпустить эти ресурсы, когда-либо. John Saunders
Именно поэтому класс реализует IDisposable. ГК не может их выпустить, потому что не знает о них. Класс, содержащий эти неуправляемые ресурсы, должен освобождать их при вызове метода Dispose. Mike Hofer
Но вы сказали: «Эти ресурсы не освобождаются, пока не придет сборщик мусора и не соберет объект». Освобождение этих неуправляемых ресурсов вообще не зависит от сборщика мусора. John Saunders
На самом деле, Microsoft так сказала. Видеть Msdn.microsoft.com / EN-US / библиотека / system.idisposable.aspx. Так что, по правде говоря, правильный релиз этих ресурсов Делает зависит от реализации IDisposable. GC не знает, что вы выделили неуправляемый ресурс; следовательно, это не может выпустить это для вас. Когда приходит время собирать ваш объект, вам предоставляется возможность освободить эти объекты самостоятельно посредством реализации IDisposable. Mike Hofer
Вам не дают изменений для освобождения объектов, если вы не внедрили финализатор. Тот, кто использует объект, реализующий IDisposable, не может зависеть от того, было ли это сделано. Единственный способ быть уверенным в том, что все неуправляемые ресурсы будут освобождены, - это явным образом вызвать Dispose самостоятельно и не предполагать, что GC позаботится об этом. Обычный способ обеспечения вызова Dispose - использование оператора. John Saunders
1

но при использовании SqlCommand его следует утилизировать после использования. Вы можете либо просто вызвать .Dispose (), либо просто поместить его в блок using, например:


using(DbCommand cmd = new DbCommand(foo, bar))
{
     // use cmd object
}

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