Вопрос

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

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

Решение

Сборка мусора для памяти. Вам нужно избавиться от ресурсов, не связанных с памятью - файловых дескрипторов, сокетов, дескрипторов GDI +, соединений с базой данных и т. Д. Обычно это то, что лежит в основе типа IDisposable , хотя реальный дескриптор может быть довольно длинным в цепочке. ссылок. Например, вы можете утилизировать XmlWriter , который располагает StreamWriter , на который он ссылается, который располагает FileStream У it есть ссылка, которая освобождает дескриптор файла.

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

Немного дополню другие комментарии:

Метод Dispose() следует вызывать для всех объектов, имеющих ссылки на неуправляемые ресурсы.Примерами могут служить потоки файлов, соединения с базами данных и т. д.Основное правило, которое работает в большинстве случаев:«Если объект .NET реализует IDisposable, вам следует вызвать Dispose(), когда вы закончите работу с объектом.

Однако следует иметь в виду еще некоторые вещи:

  • Вызов Dispose не дает вам контроля над тем, когда объект фактически уничтожается и освобождается память.GC делает это за нас и делает это лучше, чем мы можем.
  • Dispose очищает все собственные ресурсы, вплоть до базовых классов, как указал Джон.Затем он вызывает SuppressFinalize(), чтобы указать, что объект готов к восстановлению и дальнейшая работа не требуется.Следующий запуск GC очистит его.
  • Если Dispose не вызывается, то GC обнаруживает, что объект нуждается в очистке, но сначала необходимо вызвать Finalize, чтобы убедиться, что ресурсы освобождены, что запрос Finalize ставится в очередь и GC движется дальше, поэтому отсутствие вызов Dispose заставляет запустить еще один сборщик мусора, прежде чем объект можно будет очистить.Это приведет к тому, что объект будет переведен в следующее «поколение» GC.Это может показаться не таким уж большим делом, но в приложениях с ограниченным объемом памяти повышение объектов до более высоких поколений GC может привести к тому, что приложение с большим объемом памяти станет приложением с нехваткой памяти.
  • Не реализуйте IDisposable в своих собственных объектах, если в этом нет крайней необходимости.Плохо реализованные или ненужные реализации могут фактически усугубить ситуацию, а не улучшить ее.Некоторые хорошие рекомендации можно найти здесь:

    Реализация метода Dispose

    Или прочитайте весь раздел MSDN, посвященный сбору мусора.

Потому что объекты иногда держат ресурсы рядом с памятью. GC освобождает память; IDisposable, так что вы можете выпустить что-нибудь еще.

потому что вы хотите контролировать, когда ресурсы, удерживаемые вашим объектом, будут очищены.

Видите, GC работает, но он делает это, когда ему это нравится, и даже тогда финализаторы, которые вы добавляете к своим объектам, будут вызываться только после 2 коллекций GC. Иногда вы хотите убрать эти объекты немедленно.

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

Примеры ресурсов, которые вы хотите немедленно очистить: дескрипторы базы данных, дескрипторы файлов, сетевые дескрипторы.

Чтобы использовать ключевое слово using, объект должен реализовывать IDisposable. http://msdn.microsoft.com/en-us /library/yh598w02(VS.71).aspx

Интерфейс IDisposable часто описывается в терминах ресурсов, но в большинстве таких описаний не учитывается, что такое «ресурс». действительно значит.

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

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

Чтобы поместить вещи в «ресурсы», объект получает ресурс, когда он просит внешнюю сущность сделать что-то от его имени (как правило, хотя и не обязательно, предоставляя исключительное использование чего-либо) до дальнейшего уведомления, и освобождает ресурс, когда он сообщает, что внешнему объекту его услуги больше не требуются. Код, который получает ресурс, не получает «вещь» настолько, насколько это влечет за собой обязательство; освобождение ресурса не оставляет «вещь», а выполняет обязательство.

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