Что такое IDisposable?

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

Ответ 1

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

Ответ 2

Развертывание бит в других комментариях:

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

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

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

    Внедрение метода удаления

    Или прочитайте весь раздел MSDN в Garbage Collection

Ответ 3

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

Ответ 4

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

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

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

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

Ответ 6

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

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

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

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