IDisposable интерфейс - PullRequest
       0

IDisposable интерфейс

12 голосов
/ 11 октября 2010

Я знаю об IDisposable интерфейсе и его использовании в .net, но у меня возникает вопрос: если я пишу весь управляемый код, имеет ли смысл реализация IDisposable интерфейса?

iзнаю, когда и как использовать Idisposible, но мой вопрос в том, пишу ли я весь управляемый код, скажем, простой класс, ничего дорогого в нем, поэтому, если я реализую IDisposable в этом классе и сделаю некоторую очистку, например, освобождение некоторых глобальных значенийсмысл? * * 1006

Ответы [ 6 ]

11 голосов
/ 11 октября 2010

Нет, вам может не понадобиться использовать интерфейс IDisposble. Тем не менее, рекомендуется при определенных обстоятельствах (я мог бы добавить позже, как я помню :)):

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

  2. У вас есть несколько открытых потоков, которые живы до тех пор, пока объект класса не умрет. Несмотря на то, что такими реализациями файлов / сети и т. Д. Управляют, они углубляются в описатели в режиме Win32. Следовательно, вы получаете возможность написать метод Dispose, в котором вы можете закрыть потоки. То же самое верно для объектов GDI и некоторых других.

  3. Вы пишете класс, который использует неуправляемые ресурсы, и вы хотите отправить сборку третьим лицам. Вам лучше использовать одноразовый шаблон, чтобы убедиться, что вы можете освободить ручки, чтобы избежать утечки.

  4. Спасибо суперкату за это: ваш класс реализует множество обработчиков событий и подключает их к событиям. Объекты классов, которые представляют события, такие как Form и т. Д., Не будут освобождены GC, так как реализации, локальные для вашего класса (возможно), все еще подключены к этим событиям. Вы можете отцепить эти обработчики событий в Dispose; снова помогая GC.

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

7 голосов
/ 11 октября 2010

Практическое правило: вам нужно реализовать IDisposable, если ваш тип имеет переменную-член, которая сама является IDisposable, или если она неуправляема.GC является недетерминированным в .NET, а IDisposable дает вам детерминированный способ не восстанавливать память, а восстанавливать resources .Поэтому, когда Dispose () вызывается, GC не освобождает вашу память сразу, но вы можете детально детально очистить неуправляемые ресурсы (например, убедиться, что ваши соединения с базой данных закрыты, и вы не используете максимальное количество соединений на сервере).

3 голосов
/ 11 октября 2010

Редко упоминаемый сценарий, в котором правильное использование iDisposable критическое - это объект с коротким сроком полезного использования, который получает события от долгоживущего объекта. Метод Dispose для такого объекта должен отписаться о его событиях. Если объект не отменяет подписку сам по себе, он не будет иметь право на сборку мусора до тех пор, пока объект (ы), события которого он подписал, не станет пригодным для сбора мусора; это вполне может быть никогда.

Например, некоторые типы перечислителей должны подписываться на сообщения «объект изменен». Было бы вполне вероятно, что многие тысячи таких перечислителей будут созданы во время выполнения долгосрочной программы. Если бы такие перечислители не были отписаны, они могли бы эффективно засорить систему, даже если они никогда не использовали никаких ресурсов, кроме управляемой памяти.

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

3 голосов
/ 11 октября 2010

Если у вас есть ресурс, который необходимо восстановить (например, File), вы хотите иметь IDisposible, чтобы явно закрыть его и не ждать, пока GC выполнит его.

2 голосов
/ 11 октября 2010

Да, даже если у вас нет управляемых ресурсов, IDisposable может быть полезен.Зачем?Поскольку вы можете использовать метод Dispose для сброса ссылок на объекты обратно на null.

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

0 голосов
/ 11 октября 2010

Имеет ли это какой-то смысл?

Нет, делайте ваш объект одноразовым, только если его создание дорого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...