Изхвърлете обектите във Visual Basic

click fraud protection

В статията, Кодиране на нови инстанции на обекти, писах за различните начини, които нов могат да бъдат създадени екземпляри от обекти. Обратният проблем, разпореждането с даден обект, е нещо, за което няма да се налага да се тревожите във VB.NET много често. .NET включва технология, наречена Събирач на боклук (GC), който обикновено се грижи за всичко зад кулисите мълчаливо и ефективно. Но понякога, обикновено когато използвате файлови потоци, sql обекти или графични (GDI +) обекти (т.е. неуправляеми ресурси), може да се наложи да поемете контрола над разпореждането с обекти в собствения си код.

Първо, някои предистория

Точно като а мошеникструктор (на нов ключова дума) създава нова обект, a деstructor е метод, който се нарича, когато обект е унищожен. Но има уловка. Хората, които създадоха .NET разбраха, че това е формула за грешки, ако две различни части от кода всъщност могат да унищожат обект. Така че .NET GC всъщност контролира и обикновено това е единственият код, който може да унищожи инстанцията на обекта. GC унищожава обект, когато реши, а не преди. Обикновено, след като обект напусне обхват, това е така

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

(Welllll... Вярно е почти през цялото време. Можете да се обадите GC.Collect и сила a цикъл за събиране на боклука, но властите всеобщо казват, че това е " лошо идея и напълно ненужна.)

Например, ако кодът ви е създал a клиент обект, може да изглежда, че този код ще го унищожи отново.

Клиент = Нищо

Но не става. (Задаването на обект на Нищо обикновено се нарича, dereferencing обекта.) Всъщност това просто означава, че променливата вече не е свързана с обект. След известно време GC ще забележи, че обектът е достъпен за унищожаване.

Между другото, за управлявани обекти нищо от това не е наистина необходимо. Въпреки че обект като бутон ще предлага метод на разположение, не е необходимо да го използвате и малко хора го правят. Компонентите на Windows Forms например се добавят към обект с име елементи. Когато затворите формуляр, методът му за разпореждане се извиква автоматично. Обикновено трябва да се притеснявате само за нещо от това, когато използвате неуправляеми обекти и дори тогава само за да оптимизирате програмата си.

Препоръчителният начин за освобождаване на всички ресурси, които могат да бъдат държани от обект, е да се обадите на Изхвърлете метод за обекта (ако има такъв) и след това обезвреждане на обекта.

Клиент. Унищожаване () Клиент = Нищо

Тъй като GC ще унищожи осиротял обект, независимо дали сте задали променливата на обекта на Нищо, всъщност не е необходимо.

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

В серията GDI +, the Използвайки блок се използва да се използва доста често за управление на тези досадни графични обекти. Например ...

Използване на myBrush като LinearGradientBrush _. = Нов LinearGradientBrush (_. Мен. ClientRectangle, _. Цвят. Син цвят. Червен, _. LinearGradientMode. Хоризонтална) <... ...> Прекратяване на използването

myBrush се изхвърля автоматично, когато се изпълнява края на блока.

Подходът на GC за управление на паметта е голяма промяна от начина, по който VB6 го направи. COM обектите (използвани от VB6) бяха унищожени, когато вътрешен брояч на справки достигна нула. Но беше твърде лесно да се направи грешка, така че вътрешният брояч беше изключен. (Тъй като паметта беше свързана и не беше достъпна за други обекти, когато това се случи, това се нарече "изтичане на памет".) Вместо това GC всъщност проверява дали нещо препраща към даден обект и го унищожава, когато няма повече препратки. Подходът на GC има добра история на езици като Java и е едно от големите подобрения в .NET.

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

Ако кодирате свой собствен обект, който използва неуправляеми ресурси, трябва да използвате IDisposable интерфейс за обекта. Microsoft прави това лесно, като включва кодов фрагмент, който създава правилния модел за вас.


Щракнете тук, за да покажете илюстрацията
Щракнете върху бутона Назад в браузъра си, за да се върнете

Добавеният код изглежда така (VB.NET 2008):

 Клас ResourceClass. Внедрява IDisposable. „За откриване на излишни повиквания. Частно разположени като булева = фалшива. „Идентифицируем. Защитено сменяемо подразделение (_. ByVal се разпорежда като Boolean) Ако не Me.disposed тогава. Ако изхвърляте тогава. „Безплатно друго състояние (управлявани обекти). Край Ако. „Освободете собственото си състояние (неуправляеми обекти). „Задайте големи полета на нула. Край Ако. Me.disposed = Вярно. Край Sub. #Region "Поддръжка на IDisposable" "Този код е добавен от Visual Basic към. 'правилно прилагайте модела за еднократна употреба. Публична подразделение () Прилага ИД за еднократна употреба. Изхвърлете. „Не променяйте този код. „Поставете код за почистване. „Изхвърлете (ByVal изхвърля като Boolean) по-горе. Изхвърлете (True) GC.SuppressFinalize (Me) End Sub. Защитени отмени Sub Finalize () 'Не променяйте този код. „Поставете код за почистване. „Изхвърлете (ByVal изхвърля като Boolean) по-горе. Изхвърлете (невярно) MyBase. Финализиране () Край Sub. #End Region. Краен клас 

Изхвърлете е почти "принуден" модел на дизайн на разработчици в .NET. Наистина има само един правилен начин да го направите и това е това. Може да си мислите, че този код прави нещо вълшебно. Не става.

Първо обърнете внимание, че вътрешното знаме разположени просто късо съединение на цялата работа, за да можете да се обадите Изхвърляне (изхвърляне) толкова често, колкото ви харесва.

Кодът ...

 GC.SuppressFinalize (Me) 

... прави вашия код по-ефективен, като казва на GC, че обектът вече е бил унищожен („скъпа“ операция по отношение на цикли на изпълнение). Финализирането е защитено, защото GC го извиква автоматично, когато обект е унищожен. Никога не трябва да се обаждате на Finalize. Булев обезвреждане казва кода дали вашият код е инициирал обезвреждането на обекта (True) или дали GC го е направил (като част от Финализиране под. Обърнете внимание, че единственият код, който използва Boolean обезвреждане е:

 Ако изхвърляте тогава. „Безплатно друго състояние (управлявани обекти). Край Ако 

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

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

Когато извличате клас от a базов клас който внедрява IDisposable, не е нужно да отменяте нито един от базовите методи, освен ако не използвате други ресурси, които също трябва да бъдат изхвърлени. Ако това се случи, производният клас трябва да отмени метода Dispose (dispose) на базовия клас, за да се разпорежда с ресурсите на извлечения клас. Но не забравяйте да се обадите на метода Dispose (disposition) на базовия клас.

Защитени отметки Sub Dispose (ByVal разпорежда като булева) Ако не Me.disposed тогава. Ако изхвърляте тогава. „Добавете кода си към безплатни управлявани ресурси. Край Ако. „Добавете кода си към безплатни неуправляеми ресурси. Край Ако. MyBase. Изхвърляне (изхвърляне) Край Sub

Темата може да бъде леко затрудняваща. Целта на обяснението тук е да „демистифицираме“ какво всъщност се случва, защото повечето от информацията, която можете да намерите, не ви казва!

instagram story viewer