V článku „Kódování nových instancí objektů“ jsem psal o různých způsobech Nový instance objektů mohou být vytvořeny. Opačný problém, kterým je likvidace objektu, je něco, o co se ve VB.NET nebudete muset starat velmi často. NET obsahuje technologii nazvanou Popelář (GC), která se obvykle stará o všechno v zákulisí tiše a efektivně. Ale občas, obvykle při použití souborových datových toků, objektů sql nebo grafických objektů (GDI +) (tj. nespravované zdroje), možná budete muset převzít kontrolu nad likvidací objektů ve svém vlastním kódu.
Za prvé, některé pozadí
Stejně jako ošiditstructor (dále jen Nový klíčové slovo) vytvoří nový objekt, a deStructor je metoda, která se volá, když je objekt zničen. Ale je tu háček. Lidé, kteří vytvořili .NET, si uvědomili, že to byl vzorec pro chyby, pokud by dva různé kusy kódu mohly skutečně zničit objekt. Takže .NET GC je vlastně pod kontrolou a je to obvykle jediný kód, který může zničit instanci objektu. GC zničí objekt, když se rozhodne a ne dříve. Normálně, když objekt opustí rozsah, je
uvolněno podle společného jazykového modulu runtime (CLR). GC ničí objekty, když CLR potřebuje více volné paměti. Z toho vyplývá, že nemůžete předvídat, kdy GC objekt skutečně zničí.(Welllll... To je pravda téměř Celou dobu. Můžeš volat GC.Collect a síla a cyklus sběru odpadu, ale úřady obecně říkají, že je to špatný nápad a zcela zbytečné.)
Například pokud váš kód vytvořil Zákazník objekt, může se zdát, že tento kód jej znovu zničí.
Zákazník = Nic
Ale ne. (Nastavení objektu na Nic se běžně nazývá, dereferencing objekt.) Ve skutečnosti to znamená, že proměnná již není s objektem spojena. O něco později si GC všimne, že objekt je k dispozici ke zničení.
Mimochodem, u spravovaných objektů není nic z toho opravdu nutné. Přestože objekt jako tlačítko nabídne metodu Dispose, není nutné jej používat a jen málo lidí ji používá. Například komponenty Windows Forms se přidají do kontejnerového objektu s názvem komponenty. Při zavření formuláře se automaticky zavolá metoda Dispose. Obvykle se s tím musíte starat pouze v případě, že používáte nespravované objekty, a dokonce i poté jen optomizujte program.
Doporučeným způsobem uvolnění prostředků, které mohou být v držení objektu, je zavolat Zlikvidujte metoda pro objekt (pokud je k dispozici) a potom dereference objektu.
Zákazník. Dispose () Zákazník = Nic
Protože GC zničí osamocený objekt, ať už nastavíte proměnnou objektu na Nothing, není to opravdu nutné.
Dalším doporučeným způsobem, jak zajistit, aby byly objekty zničeny, když již nejsou potřeba, je vložit kód, který používá objekt, do Použitím blok. Blok Použití zaručuje likvidaci jednoho nebo více takových zdrojů po dokončení kódu.
V řadě GDI + Použitím blok je používán poměrně často ke správě těchto otravných grafických objektů. Například ...
Použití myBrush jako LinearGradientBrush _. = New LinearGradientBrush (_. Mě. ClientRectangle, _. Barva. Modrá barva. Červené, _. LinearGradientMode. Horizontální) <... v k ...> Ukončete používání
myBrush je automaticky odstraněn, když je proveden konec bloku.
Přístup GC ke správě paměti je velká změna oproti způsobu, jakým to udělala VB6. COM objekty (používané VB6) byly zničeny, když interní čítač referencí dosáhl nuly. Ale bylo příliš snadné udělat chybu, takže vnitřní počítadlo bylo vypnuto. (Protože paměť byla svázána a nebyla k dispozici jiným objektům, když se to stalo, nazývalo se to „nevracení paměti“.) Místo toho GC ve skutečnosti zkontroluje, zda něco odkazuje na objekt a zničí jej, když už neexistují Reference. Přístup GC má dobrou historii v jazycích jako Java a je jedním z velkých vylepšení v .NET.
Na další stránce se podíváme do rozhraní IDisposable... rozhraní, které se použije, když potřebujete zlikvidovat nespravované objekty ve vašem vlastním kódu.
Pokud kódujete svůj vlastní objekt, který používá nespravované prostředky, měli byste použít IDisposable rozhraní pro objekt. Společnost Microsoft to usnadňuje zahrnutím fragmentu kódu, který pro vás vytvoří správný vzor.
Klepnutím sem zobrazíte obrázek
Klepnutím na tlačítko Zpět v prohlížeči se vrátíte
Přidaný kód vypadá takto (VB.NET 2008):
Třída ResourceClass. Implementace IDisposable. „Zjistit nadbytečná volání. Soukromé nakládáno jako Boolean = False. "IDISposable." Chráněné přepisovatelné dílčí likvidace (_. ByVal likvidace jako booleovský) Pokud není Me.disposed Then. Pokud je likvidujete, pak. 'Zdarma další stát (spravované objekty). Konec If. „Uvolněte svůj vlastní stát (nespravované objekty). 'Nastavit velká pole na null. Konec If. Me.disposed = True. End Sub. #Region "Podpora IDisposable" 'Tento kód přidán do jazyka Visual Basic. 'správně implementovat jednorázový vzor. Public Sub Dispose () Implementuje IDisposable. Zlikvidujte. "Neměňte tento kód." "Vložte čisticí kód." 'Zlikvidujte (ByVal likvidace jako Boolean) výše. Dispose (True) GC.SuppressFinalize (Me) End Sub. Chráněné přepsání Sub Finalize () 'Tento kód neměňte. "Vložte čisticí kód." 'Zlikvidujte (ByVal likvidace jako Boolean) výše. Zlikvidujte (False) MyBase. Finalize () End Sub. #End Region. Koncová třída
Zlikvidujte je téměř „vynucený“ vzorec pro vývojáře v .NET. Existuje opravdu jediný správný způsob, jak to udělat, a to je vše. Možná si myslíte, že tento kód dělá něco magického. To ne.
Nejprve si všimněte, že vnitřní vlajka zlikvidováno jednoduše zkratujete celou věc, abyste mohli volat Likvidace (likvidace) tak často, jak chcete.
Kód ...
GC.SuppressFinalize (Me)
... zlepší váš kód tím, že řekne GC, že objekt již byl zlikvidován („nákladná“ operace, pokud jde o prováděcí cykly). Finalizace je chráněna, protože GC ji volá automaticky, když je objekt zničen. Nikdy byste neměli volat Dokončit. Booleovský dispozice řekne kódu, zda váš kód zahájil likvidaci objektu (True) nebo zda to GC udělal (jako součást Dokončit sub. Všimněte si, že jediný kód, který používá logický dispozice je:
Pokud je likvidujete, pak. 'Zdarma další stát (spravované objekty). Konec If
Když zlikvidujete předmět, musí být zlikvidovány všechny jeho zdroje. Když CLR Popelář zlikviduje objekt, musí se zlikvidovat pouze nespravované prostředky, protože sběratel odpadu automaticky spravuje spravované prostředky.
Myšlenka tohoto fragmentu kódu je, že přidáte kód, abyste se mohli starat o spravované a nespravované objekty v označených místech.
Když odvodíte třídu z a základní třída která implementuje IDisposable, nemusíte přepisovat žádnou ze základních metod, pokud nepoužijete jiné zdroje, které je také nutné zlikvidovat. Pokud k tomu dojde, měla by odvozená třída přepsat metodu Dispose (disposing) základní třídy, aby se zbavily zdroje odvozené třídy. Nezapomeňte však zavolat metodu Dispose (likvidace) základní třídy.
Chráněné potlačení Sub Dispose (ByVal likvidace jako Boolean) Pokud není Me.disposed Then. Pokud je likvidujete, pak. 'Přidejte svůj kód do spravovaných zdrojů zdarma. Konec If. 'Přidejte svůj kód k uvolnění nespravovaných zdrojů. Konec If. MyBase. Likvidace (likvidace) End Sub
Objekt může být lehce ohromující. Účelem tohoto vysvětlení je „demystifikovat“ to, co se ve skutečnosti děje, protože většina informací, které můžete najít, vám to neříká!