I artikeln, Coding New Instances of Objects, skrev jag om de olika sätten Ny instanser av objekt kan skapas. Det motsatta problemet, att bortskaffa ett objekt, är något som du inte behöver oroa dig för i VB.NET ofta. .NET har en teknik som heter Skräp samlare (GC) som vanligtvis tar hand om allt bakom kulisserna tyst och effektivt. Men ibland, vanligtvis när du använder filströmmar, sql-objekt eller grafik (GDI +) -objekt (det vill säga obemanade resurser), kan du behöva ta kontroll över kassering av föremål i din egen kod.
Först, lite bakgrund
Precis som en lurakonstruktör ( Ny nyckelord) skapar ett nytt objekt, a dekonstruktor är en metod som kallas när ett objekt förstörs. Men det finns en fångst. De människor som skapade .NET insåg att det var en formel för buggar om två olika kodkoder faktiskt kunde förstöra ett objekt. Så .NET GC har faktiskt kontroll och det är vanligtvis den enda koden som kan förstöra objektets instans. GC förstör ett objekt när det bestämmer sig för och inte förut. Normalt, efter att ett objekt lämnar omfattningen, är det det
släppte av vanligt språk runtime (CLR). GC förstör objekt när CLR behöver mer ledigt minne. Så slutet är att du inte kan förutsäga när GC faktiskt kommer att förstöra objektet.(Welllll... Det är sant nästan hela tiden. Du kan ringa GC.Collect och tvinga a skräpuppsamlingscykel, men myndigheterna säger universellt att det är en dålig idé och helt onödigt.)
Till exempel, om din kod har skapat en Kund objekt kan det tyckas att den här koden förstör den igen.
Kund = ingenting
Men det gör det inte. (Att ställa ett objekt till ingenting kallas vanligtvis, dereferencing objektet.) Det betyder faktiskt bara att variabeln inte längre är associerad med ett objekt. Någon gång senare kommer GC att märka att objektet är tillgängligt för förstörelse.
För hanterade objekt är förresten inget av detta verkligen nödvändigt. Även om ett objekt som en knapp kommer att erbjuda en disposeringsmetod, är det inte nödvändigt att använda det och få människor gör det. Windows Forms-komponenter läggs till exempel till ett behållareobjekt med namnet komponenter. När du stänger ett formulär anropas dess avfallsmetod automatiskt. Vanligtvis behöver du bara oroa dig för något av detta när du använder obegränsade objekt, och till och med bara för att optimera ditt program.
Det rekommenderade sättet att frigöra alla resurser som kan hållas av ett objekt är att ringa till Avfalls metod för objektet (om ett är tillgängligt) och därefter bort objektet.
Kund. Dispose () Kund = ingenting
Eftersom GC kommer att förstöra ett föräldralöst objekt, oavsett om du ställer in objektvariabeln till ingenting, är det inte riktigt nödvändigt.
Ett annat rekommenderat sätt att se till att objekt förstörs när de inte behövs längre är att sätta koden som använder ett objekt i en Använder sig av blockera. Ett användningsblock garanterar avyttring av en eller flera sådana resurser när din kod är klar med dem.
I GDI + -serien, Använder sig av blocket används ganska ofta för att hantera de irriterande grafikobjekten. Till exempel ...
Använda myBrush As LinearGradientBrush _. = Ny LinearGradientBrush (_. Mig. ClientRectangle, _. Färg. Blå färg. Röd, _. LinearGradientMode. Horisontell) <... mer kod ...> Avsluta med
myBrush bortskaffas automatiskt när slutet av blocket körs.
GC-strategin för att hantera minne är en stor förändring från det sätt som VB6 gjorde det. COM-objekt (används av VB6) förstördes när en intern referensräknare nådde noll. Men det var för lätt att göra ett misstag så att den interna räknaren var avstängd. (Eftersom minnet var bundet och inte tillgängligt för andra objekt när detta hände kallades detta för "minnesläcka".) Istället kontrollerar GC faktiskt om något hänvisar till ett objekt och förstör det när det inte finns fler referenser. GC-strategin har en god historia på språk som Java och är en av de stora förbättringarna i .NET.
På nästa sida tittar vi på det IDisponerbara gränssnittet... gränssnittet som ska användas när du behöver kassera obegränsade objekt i din egen kod.
Om du koderar ditt eget objekt som använder ostyrda resurser bör du använda IDisposable gränssnitt för objektet. Microsoft gör det enkelt genom att ta med ett kodavsnitt som skapar rätt mönster för dig.
Klicka här för att visa bilden
Klicka på knappen Tillbaka i webbläsaren för att återgå
Koden som läggs till ser ut så här (VB.NET 2008):
Klass ResourceClass. Implementerar IDisposable. "Att upptäcka redundanta samtal. Privat disponerat som booleskt = falskt. "IDisponerbar. Skyddat överbrytbart underhantering (_. ByVal kasserar som boolesk) Om inte Me.disponeras sedan. Om du kasserar sedan. "Gratis annat tillstånd (hanterade objekt). Sluta om. "Frigör ditt eget tillstånd (obemanade objekt). 'Ställ in stora fält till null. Sluta om. Me.disposed = Sant. Avsluta under. #Region "IDisposable Support" 'Denna kod tillagd av Visual Basic till. "implementera engångsmönstret korrekt. Public Sub Dispose () Implementerar IDisposable. Avyttra. "Ändra inte den här koden. "Sätt in rensningskod. "Kassera (ByVal kassera som Boolean) ovan. Kassera (sant) GC.SuppressFinalize (Me) End Sub. Protected Overrides Sub Finalize () 'Ändra inte den här koden. "Sätt in rensningskod. "Kassera (ByVal kassera som Boolean) ovan. Kassera (False) MyBase. Slutför () Slut Sub. #End Region. Slutklass
Avfalls är nästan ett "påtvingat" utvecklingsmönster för .NET. Det finns egentligen bara ett korrekt sätt att göra det och det är det. Du kanske tror att den här koden gör något magiskt. Det gör det inte.
Först notera att den interna flaggan anordnad helt enkelt kortslutningar hela saken så att du kan ringa Kassera (kassera) så ofta du vill.
Koden ...
GC.SuppressFinalize (Me)
... gör din kod effektivare genom att berätta för GC att objektet redan har bortsett sig (en "dyr" operation när det gäller körningscykler). Slutföra är skyddat eftersom GC anropar det automatiskt när ett objekt förstörs. Du ska aldrig ringa slutföra. The Boolean anordna berättar koden om din kod initierade objektets förfogande (True) eller om GC gjorde det (som en del av Avsluta sub. Observera att den enda koden som använder Boolean anordna är:
Om du kasserar sedan. "Gratis annat tillstånd (hanterade objekt). Sluta om
När du kasserar ett objekt måste alla dess resurser bortskaffas. När CLR skräp samlare bortskaffar ett föremål endast de obestånda resurserna måste bortskaffas eftersom avfallssamlaren automatiskt tar hand om de hanterade resurserna.
Tanken bakom det här kodavsnittet är att du lägger till kod för att ta hand om hanterade och okontrollerade objekt på de angivna platserna.
När du hämtar en klass från a basklass som implementerar IDisposable, behöver du inte åsidosätta någon av basmetoderna om du inte använder andra resurser som också behöver kasseras. Om det händer bör den härledda klassen åsidosätta basklassens avyttringsmetod för att bortskaffa den härledda klassens resurser. Men kom ihåg att ringa basklassens avfallsmetod.
Skyddade åsidosättningar Delhantera (ByVal kasseras som boolesk) Om inte Me.disponeras sedan. Om du kasserar sedan. "Lägg till din kod i gratis hanterade resurser. Sluta om. "Lägg till din kod för att frigöra obemanade resurser. Sluta om. MyBase. Kassera (kassera) Avsluta under
Ämnet kan vara något överväldigande. Syftet med förklaringen här är att "avmystifiera" vad som faktiskt händer eftersom den mesta informationen du hittar inte berättar för dig!