Распоряжаться объектами в Visual Basic

В статье «Кодирование новых экземпляров объектов» я писал о различных способах новый экземпляры объектов могут быть созданы. Противоположная проблема - избавление от объекта - это то, о чем вам не придется часто беспокоиться в VB.NET. .NET включает технологию под названием Уборщик мусора (GC), который обычно заботится обо всем за кадром тихо и эффективно. Но иногда, как правило, при использовании файловых потоков, объектов SQL или графических (GDI +) объектов (то есть неуправляемые ресурсы), возможно, вам придется взять под контроль удаление объектов в вашем собственном коде.

Во-первых, немного предыстории

Просто как противСтроитель ( новый Ключевое слово) создает новый объект, деStructor - это метод, который вызывается при уничтожении объекта. Но тут есть подвох. Люди, создавшие .NET, поняли, что это формула ошибок, если два разных куска кода действительно могут уничтожить объект. Таким образом, .NET GC фактически контролирует и обычно является единственным кодом, который может уничтожить экземпляр объекта. GC уничтожает объект, когда решает, а не раньше. Обычно после того, как объект покидает область видимости, он

instagram viewer
выпущенный общеязыковой средой исполнения (CLR). ГК истребляет объекты, когда CLR требуется больше свободной памяти. Итак, суть в том, что вы не можете предсказать, когда GC действительно уничтожит объект.

(Welllll... Это правда около Все время. Вы можете позвонить GC.Collect и заставить цикл сбора мусора, но власти повсеместно говорят, что это Плохо идея и совершенно ненужная.)

Например, если ваш код создал Покупатель объект, может показаться, что этот код уничтожит его снова.

Клиент = ничего

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

Кстати, для управляемых объектов ничего из этого действительно не нужно. Хотя такой объект, как Button, будет предлагать метод Dispose, его использовать не обязательно, и мало кто это делает. Компоненты Windows Forms, например, добавляются в контейнерный объект с именем компоненты. Когда вы закрываете форму, ее метод Dispose вызывается автоматически. Как правило, вам нужно беспокоиться об этом только при использовании неуправляемых объектов, и даже тогда, чтобы просто оптимизировать вашу программу.

Рекомендуемый способ высвобождения любых ресурсов, которые могут удерживаться объектом, заключается в вызове Dispose метод для объекта (если таковой имеется) и затем разыменование объекта.

Покупатель. Dispose () Клиент = ничего

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

Другой рекомендуемый способ убедиться, что объекты уничтожаются, когда они больше не нужны, - поместить код, использующий объект, в С помощью блок. Блок Using гарантирует удаление одного или нескольких таких ресурсов, когда ваш код закончен с ними.

В серии GDI + С помощью блок используется довольно часто для управления этими надоедливыми графическими объектами. Например ...

Использование myBrush в качестве LinearGradientBrush _. = New LinearGradientBrush (_. Мне. ClientRectangle, _. Цвет. Синий цвет. Красный, _. LinearGradientMode. Горизонтальный) <... ...> Конец использования

MyBrush утилизируется автоматически при выполнении конца блока.

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

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

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


Нажмите здесь, чтобы отобразить иллюстрацию
Нажмите кнопку «Назад» в вашем браузере, чтобы вернуться

Добавленный код выглядит следующим образом (VB.NET 2008):

 Класс ResourceClass. Реализует IDisposable. 'Для обнаружения избыточных звонков. Частное распоряжение As Boolean = False. 'IDisposable. Защищенная переопределенная подчиненная утилита (_. ByVal, удаляющий как логическое значение) Если не я. Если избавиться тогда. «Свободное другое состояние (управляемые объекты). Конец если. «Освободи свое собственное состояние (неуправляемые объекты). 'Установить большие поля на ноль. Конец если. Me.disposed = True. End Sub. #Region "IDisposable Support" 'Этот код, добавленный Visual Basic для. правильно реализовать одноразовый шаблон. Public Sub Dispose () Реализует IDisposable. Dispose. «Не меняйте этот код. 'Вставьте код очистки в. 'Утилизировать (ByVal избавляется как логическое значение) выше. Dispose (True) GC.SuppressFinalize (Me) End Sub. Protected Overrides Sub Finalize () 'Не меняйте этот код. 'Вставьте код очистки в. 'Утилизировать (ByVal избавляется как логическое значение) выше. Уничтожить (Ложь) MyBase. Finalize () End Sub. # Конечная область. Конечный класс 

Dispose является почти «принудительным» шаблоном разработки для разработчиков в .NET. Там действительно только один правильный способ сделать это, и это все. Вы можете подумать, что этот код делает что-то волшебное. Это не так.

Сначала обратите внимание, что внутренний флаг расположенный просто замыкает все это, так что вы можете позвонить Утилизировать (утилизировать) так часто, как вам нравится.

Код ...

 GC.SuppressFinalize (Me) 

... делает ваш код более эффективным, сообщая GC, что объект уже удален («дорогая» операция с точки зрения циклов выполнения). Finalize защищен, потому что GC вызывает его автоматически, когда объект уничтожается. Вы никогда не должны называть Finalize. Логическое значение утилизации сообщает коду, инициировал ли ваш код удаление объекта (True) или GC сделал это (как часть Доработка к югу. Обратите внимание, что единственный код, который использует логическое значение утилизации является:

 Если избавиться тогда. «Свободное другое состояние (управляемые объекты). End If 

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

Идея этого фрагмента кода заключается в том, что вы добавляете код для управления управляемыми и неуправляемыми объектами в указанных местах.

Когда вы выводите класс из базовый класс который реализует IDisposable, вам не нужно переопределять ни один из базовых методов, если вы не используете другие ресурсы, которые также должны быть утилизированы. Если это произойдет, производный класс должен переопределить метод Dispose (утилизации) базового класса, чтобы избавиться от ресурсов производного класса. Но не забудьте вызвать метод Dispose (распоряжения) базового класса.

Защищенные переопределения Sub Dispose (ByVal dispose As Boolean) Если не Me.disposed, то. Если избавиться тогда. «Добавьте свой код в бесплатные управляемые ресурсы. Конец если. «Добавьте свой код в бесплатные неуправляемые ресурсы. Конец если. MyBase. Утилизировать (утилизировать) End Sub

Предмет может быть немного подавляющим. Цель этого объяснения состоит в том, чтобы «демистифицировать» то, что на самом деле происходит, потому что большая часть информации, которую вы можете найти, не говорит вам!

instagram story viewer