Когда я могу реализовать IDispose в классе, а не деструктор? Я прочитал эту статью , но все еще не понимаю сути.
Я предполагаю, что если я использую IDispose для объекта, я могу явно «разрушить» его, а не ждать, пока сборщик мусора сделает это. Это верно?
Означает ли это, что я всегда должен явно вызывать Dispose для объекта? Каковы некоторые общие примеры этого?
c#
.net
dispose
destructor
Джордан Пармер
источник
источник
using
конструкции.Ответы:
Финализатор (он же деструктор) является частью сборки мусора (GC) - не определено, когда (или даже если) это произойдет, поскольку GC в основном происходит в результате нехватки памяти (т.е. требуется больше места). Финализаторы обычно используются только для очистки неуправляемых ресурсов, поскольку для управляемых ресурсов будет свой собственный сбор / удаление.
Следовательно
IDisposable
, используется для детерминированной очистки объектов, то есть сейчас. Он не собирает память объекта (которая все еще принадлежит GC), но используется, например, для закрытия файлов, подключений к базе данных и т. Д.По этому поводу много предыдущих тем:
Наконец, обратите внимание, что
IDisposable
объект нередко также имеет финализатор; в этом случаеDispose()
обычно вызываетGC.SuppressFinalize(this)
, что означает, что GC не запускает финализатор - он просто выбрасывает память (намного дешевле). Финализатор все равно работает, если вы забылиDispose()
объект.источник
Роль
Finalize()
метода состоит в том, чтобы гарантировать, что объект .NET может очищать неуправляемые ресурсы при сборке мусора . Однако такие объекты, как соединения с базой данных или обработчики файлов, должны быть освобождены как можно скорее, вместо того, чтобы полагаться на сборку мусора. Для этого вы должны реализоватьIDisposable
интерфейс и освободить ресурсы вDispose()
методе.источник
В MSDN есть очень хорошее описание :
источник
Единственное, что должно быть в деструкторе C #, - это такая строка:
Вот и все. В этом методе никогда не должно быть ничего другого.
источник
Ваш вопрос о том, всегда ли вам звонить
Dispose
, обычно вызывает жаркие споры. В этом блоге вы найдете интересную точку зрения уважаемых людей в сообществе .NET.Лично я считаю, что позиция Джеффри Рихтера о том, что колл
Dispose
не является обязательным, невероятно слабая. В обоснование своего мнения он приводит два примера.В первом примере он говорит, что вызов
Dispose
элементов управления Windows Forms утомителен и не нужен в обычных сценариях. Однако он не упоминает, чтоDispose
фактически вызывается автоматически контейнерами управления в этих основных сценариях.Во втором примере он заявляет, что разработчик может ошибочно предположить, что экземпляр from
IAsyncResult.WaitHandle
должен быть агрессивно удален, не осознавая, что свойство лениво инициализирует дескриптор ожидания, что приводит к ненужному снижению производительности. Но проблема с этим примером заключается в том, чтоIAsyncResult
сам по себе не соответствует собственным опубликованным рекомендациям Microsoft по работе сIDisposable
объектами. То есть, если класс содержит ссылку наIDisposable
тип, тогда должен быть реализован сам классIDisposable
. ЕслиIAsyncResult
следовать этому правилу, то его собственныйDispose
метод мог бы принять решение относительно того, какие из составляющих его членов необходимо избавиться.Так что, если у кого-то не будет более веских аргументов, я буду придерживаться принципа «всегда вызывать Dispose» с пониманием того, что будут некоторые второстепенные случаи, которые возникают в основном из-за неправильного выбора дизайна.
источник
На самом деле это довольно просто. Я знаю, что на него ответили, но я попробую еще раз, но постараюсь сделать его как можно проще.
Деструктор вообще не следует использовать. Это только запуск. Net хочет, чтобы он работал. Он будет запускаться только после цикла сборки мусора. Он может никогда не запуститься в течение жизненного цикла вашего приложения. По этой причине вы никогда не должны помещать в деструктор код, который «должен» быть запущен. Вы также не можете полагаться на то, что какие-либо существующие объекты в классе будут существовать при его запуске (возможно, они уже были очищены, поскольку порядок, в котором выполняются деструкторы, не гарантируется).
IDisposible следует использовать всякий раз, когда у вас есть объект, который создает ресурсы, требующие очистки (например, дескрипторы файлов и графики). Фактически, многие утверждают, что все, что вы помещаете в деструктор, должно быть помещено в IDisposable по причинам, перечисленным выше.
Большинство классов вызывают dispose при выполнении финализатора, но это просто надежная защита, и на него никогда нельзя полагаться. Вы должны явно удалить все, что реализует IDisposable, когда вы закончите с этим. Если вы действительно реализуете IDisposable, вам следует вызвать dispose в финализаторе. См. Пример на http://msdn.microsoft.com/en-us/library/system.idisposable.aspx .
источник
Вот еще одна прекрасная статья, которая проясняет туман вокруг IDisposable, GC и dispose.
Крис Лайонс: WebLog проясняет утилизацию
источник