IDisposable интерфейс
Я знаю о IDisposable
Интерфейс и его использование в.net, но у меня есть вопрос, что если я пишу весь управляемый код, выполняет ли IDisposable
Интерфейс имеет смысл?
я знаю, когда и как использовать Idisposible, но мой вопрос: пишу ли я весь управляемый код, скажем, простой класс, ничего дорогого в нем, так что, если я реализую IDisposable
в этом классе и сделать некоторую очистку, такую как освобождение некоторых глобальных значений, имеет ли смысл?
6 ответов
Нет, вам может не понадобиться использовать интерфейс IDisposble. Тем не менее, рекомендуется при определенных обстоятельствах (я мог бы добавить позже, как я помню:)):
В вашем классе много объектов, и существует множество перекрестных ссылок. Несмотря на то, что все это управляется, GC может быть не в состоянии восстановить память из-за живых ссылок. У вас есть шанс (кроме написания финализатора) распутать ссылки и разбить ссылки так, как вы их прикрепили. Следовательно, вы помогаете ГК восстановить память.
У вас есть несколько открытых потоков, которые живы до тех пор, пока объект класса не умрет. Несмотря на то, что такими реализациями файлов / сети и т. Д. Управляют, они углубляются в дескрипторы в режиме Win32. Следовательно, вы получаете возможность написать
Dispose
метод, где вы можете закрыть потоки. То же самое верно для объектов GDI и некоторых других.Вы пишете класс, который использует неуправляемые ресурсы, и хотите отправить сборку третьим лицам. Вам лучше использовать одноразовый шаблон, чтобы убедиться, что вы можете освободить ручки, чтобы избежать утечки.
Спасибо суперкатам за это: ваш класс реализует множество обработчиков событий и подключает их к событиям. Объекты классов, которые выставляют события, как
Form
и т.д., не будет освобожден GC, так как реализации, локальные для вашего класса (возможно), все еще подключены к этим событиям. Вы можете отцепить эти обработчики событий вDispose
; снова помогает GC.
Хм... я не могу вспомнить больше сейчас, но если класс сложен в своем поведении, вы можете переосмыслить, почему вы не хотите реализовать IDisposable
интерфейс.
Практическое правило: вам нужно реализовать IDisposable, если ваш тип имеет переменную-член, которая сама является IDisposable, или если она неуправляема. GC является недетерминированным в.NET, а IDisposable дает вам детерминированный способ не вернуть память, а вернуть ресурсы. Поэтому, когда Dispose() вызывается, ваша память не сразу освобождается GC, но вы можете детерминистически очистить неуправляемые ресурсы (например, убедитесь, что ваши соединения с базой данных закрыты, и вы не используете максимальное количество соединений на сервере).
Если у вас есть ресурс, который необходимо восстановить (например, File), вы хотите иметь IDisposible, чтобы явно закрыть его и не ждать, пока GC выполнит его.
Редко упоминаемый сценарий, где правильное использование iDisposable является критическим, - это объект с коротким сроком полезного использования, который получает события от долгоживущего объекта. Метод Dispose для такого объекта должен отписаться о его событиях. Если объект не отменяет подписку сам по себе, он не будет иметь право на сборку мусора, пока объект (ы), события которого он подписал, не станет подходящим для сбора мусора; это вполне может быть никогда.
Например, некоторые типы перечислителей должны подписываться на сообщения "объект изменен". Было бы вполне вероятно, что многие тысячи таких перечислителей будут созданы во время выполнения долгосрочной программы. Если бы такие перечислители не были отписаны, они могли бы эффективно засорить систему, даже если они никогда не использовали никаких ресурсов, кроме управляемой памяти.
Обратите внимание, что, несмотря на важность удаления такого объекта, добавление финализатора для обеспечения такого удаления было бы бесполезным. Если издатель событий вышел из области действия, попытка отписаться от одного из его событий была бы в лучшем случае бесполезной и, возможно, опасной. Поскольку подписчик события не может выйти из области видимости, если только издатели всех событий, которые он получает, также не выйдут из области видимости, финализатор будет вызываться только после того, как для него ничего не останется.
Да, даже если у вас нет управляемых ресурсов, IDisposable
все еще может быть полезным. Зачем? Потому что вы можете использовать Dispose
метод для сброса ссылок на объекты обратно null
,
Обратите внимание, что это само по себе еще не освобождает ресурсы, поскольку сборка мусора недетерминирована (т. Е. Обычно она не запускается в любой момент по вашему выбору), НО она разбивает ссылки (ссылки) между объектами, делая ее более вероятно, что некоторые объекты будут иметь право на сборку мусора при следующем запуске GC.
Это имеет какой-то смысл?
Нет, делайте свой предмет одноразовым только в том случае, если его создание дорого.