Для чего нужен IDisposable? - PullRequest
       45

Для чего нужен IDisposable?

19 голосов
/ 05 марта 2009

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

Ответы [ 6 ]

48 голосов
/ 05 марта 2009

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

8 голосов
/ 05 марта 2009

Расширение немного на другие комментарии:

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

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

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

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

    Или прочитайте весь этот раздел MSDN по сборке мусора

5 голосов
/ 05 марта 2009

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

1 голос
/ 05 марта 2009

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

1 голос
/ 05 марта 2009

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

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

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

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

0 голосов
/ 26 июня 2017

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

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

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

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

...