Bortskaf genstande i Visual Basic

I artiklen Coding New Instances of Objects skrev jeg om de forskellige måder Ny forekomster af objekter kan oprettes. Det modsatte problem, bortskaffelse af et objekt, er noget, som du ikke behøver at bekymre dig om i VB.NET meget ofte. .NET inkluderer en teknologi, der kaldes Skraldemand (GC) der normalt tager sig af alt bag kulisserne lydløst og effektivt. Men lejlighedsvis, normalt ved brug af filstrømme, sql-objekter eller grafikobjekter (GDI +) (dvs. ustyrede ressourcer), skal du muligvis tage kontrol over bortskaffelse af genstande i din egen kode.

Først noget baggrund

Ligesom en conkonstruktør (the Ny nøgleord) opretter et nyt objekt, a dekonstruktor er en metode, der kaldes, når et objekt ødelægges. Men der er en fangst. De mennesker, der oprettede .NET, indså, at det var en formel for fejl, hvis to forskellige kodestykker faktisk kunne ødelægge et objekt. Så .NET GC er faktisk i kontrol, og det er normalt den eneste kode, der kan ødelægge objektets forekomst. GC ødelægger et objekt, når det beslutter at og ikke før. Når et objekt forlader rækkevidde, er det normalt

instagram viewer
udgivet af det fælles sprogkørselstid (CLR). GC ødelægger genstande, når CLR har brug for mere fri hukommelse. Så bunden er, at du ikke kan forudsige, hvornår GC faktisk vil ødelægge objektet.

(Welllll... Det er rigtigt næsten hele tiden. Du kan ringe GC.Collect og tving a affaldsindsamlingscyklus, men myndighederne siger universelt, at det er en dårlig idé og helt unødvendig.)

For eksempel, hvis din kode har oprettet en Kunde objekt, kan det se ud til, at denne kode vil ødelægge den igen.

Kunde = Intet

Men det gør det ikke. (At indstille et objekt til Intet kaldes ofte, dereferere objektet.) Det betyder faktisk bare, at variablen ikke længere er tilknyttet et objekt. På et tidspunkt senere vil GC bemærke, at objektet er tilgængeligt til destruktion.

For administrerede genstande er intet af dette rigtigt nødvendigt. Selvom et objekt som en knap tilbyder en bortskaffelsesmetode, er det ikke nødvendigt at bruge det, og få mennesker gør det. Windows Forms-komponenter føjes for eksempel til et navngivet containerobjekt komponenter. Når du lukker en formular, kaldes dens Bortskaffelsesmetode automatisk. Normalt behøver du kun at bekymre dig om noget af dette, når du bruger ikke-administrerede objekter, og endda bare for at optomisere dit program.

Den anbefalede måde at frigive alle ressourcer, der måtte være i besiddelse af et objekt, er at ringe til Kassér metode til objektet (hvis en er tilgængelig) og derefter ændre objektet.

Kunde. Kassér () Kunde = Intet

Fordi GC vil ødelægge et forældreløst objekt, uanset om du indstiller objektvariablen til Intet, er det ikke rigtig nødvendigt.

En anden anbefalet måde at sikre, at objekter ødelægges, når de ikke længere er nødvendige, er at sætte koden, der bruger et objekt i et Ved brug af blok. A Brug af blokering garanterer bortskaffelse af en eller flere sådanne ressourcer, når din kode er færdig med dem.

I GDI + -serien, Ved brug af blok bruges ganske ofte til at styre disse irriterende grafikobjekter. For eksempel ...

Brug af myBrush Som LinearGradientBrush _. = Ny LinearGradientBrush (_. Mig. ClientRectangle, _. Farve. Blå, farve. Rød, _. LinearGradientMode. Vandret) <... mere kode ...> Slut med at bruge

myBrush bortskaffes automatisk, når enden af ​​blokken udføres.

GC-tilgangen til styring af hukommelse er en stor ændring fra den måde, VB6 gjorde det på. COM-objekter (brugt af VB6) blev ødelagt, når en intern referencetæller nåede nul. Men det var for let at lave en fejl, så den interne tæller var slukket. (Da hukommelsen var bundet og ikke tilgængelig for andre objekter, da dette skete, blev dette kaldt en "hukommelseslækage".) I stedet kontrollerer GC faktisk for at se, om noget henviser til et objekt og ødelægger det, når der ikke er flere referencer. GC-metoden har en god historie på sprog som Java og er en af ​​de store forbedringer i .NET.

På den næste side ser vi på den identificerbare grænseflade... grænsefladen, der skal bruges, når du skal bortskaffe ikke-administrerede objekter i din egen kode.

Hvis du koder dit eget objekt, der bruger ikke-administrerede ressourcer, skal du bruge IDisposable interface til objektet. Microsoft gør det nemt ved at inkludere et kodestykke, der skaber det rigtige mønster for dig.


Klik her for at få vist illustrationen
Klik på knappen Tilbage i din browser for at vende tilbage

Koden, der tilføjes, ser sådan ud (VB.NET 2008):

 Class ResourceClass. Implementerer IDisposable. 'At opdage overflødige opkald. Privat bortskaffet som boolsk = falsk. 'Identificerbar. Beskyttet overfladelig subdisponering (_. ByVal bortskaffes som boolsk) Hvis ikke Me.disponeret derefter. Hvis du bortskaffer derefter. 'Fri anden tilstand (administrerede objekter). Afslut Hvis. 'Befri din egen tilstand (ikke-administrerede objekter). 'Indstil store felter til null. Afslut Hvis. Me.disposed = Sandt. Afslut under. #Region "ID-disponibel support" 'Denne kode tilføjet af Visual Basic til. 'implementer engangsmønsteret korrekt. Offentlig underhåndtering () Implementerer IDisposable. Bortskaf. 'Skift ikke denne kode. 'Sæt oprydningskode i. Bortskaf (ByVal bortskaffes som boolsk) ovenfor. Bortskaf (sand) GC.SuppressFinalize (Me) End Sub. Protected Overrides Sub Finalize () 'Skift ikke denne kode. 'Sæt oprydningskode i. Bortskaf (ByVal bortskaffes som boolsk) ovenfor. Bortskaf (falsk) MyBase. Færdiggør () Sluttund. #End Region. Slutteklasse 

Kassér er næsten et "håndhævet" udviklermønster i .NET. Der er virkelig kun en korrekt måde at gøre det på, og det er det. Du tror måske, at denne kode gør noget magi. Det gør det ikke.

Bemærk først, at det interne flag anbragt bare kortslutning det hele, så du kan ringe Bortskaf (bortskaffes) så ofte du vil.

Koden ...

 GC.SuppressFinalize (Me) 

... gør din kode mere effektiv ved at fortælle GC, at objektet allerede er bortskaffet (en 'dyr' operation med hensyn til eksekveringscyklusser). Færdiggørelse er beskyttet, fordi GC kalder det automatisk, når et objekt ødelægges. Du skal aldrig kalde færdiggørelse. Den boolske bortskaffelse fortæller koden, om din kode startede objektets bortskaffelse (sandt) eller om GC gjorde det (som en del af Afslut sub. Bemærk, at den eneste kode, der bruger Boolean bortskaffelse er:

 Hvis du bortskaffer derefter. 'Fri anden tilstand (administrerede objekter). Afslut Hvis 

Når du bortskaffer et objekt, skal alle dets ressourcer bortskaffes. Når CLR skraldemand bortskaffelse af et objekt skal kun de ikke-administrerede ressourcer bortskaffes, fordi affaldsopsamleren automatisk tager sig af de administrerede ressourcer.

Ideen bag dette kodestykket er, at du tilføjer kode for at tage sig af administrerede og ikke-administrerede objekter på de angivne placeringer.

Når du henter en klasse fra en baseklasse der implementerer IDisposable, behøver du ikke at tilsidesætte nogen af ​​basismetoderne, medmindre du bruger andre ressourcer, der også skal bortskaffes. Hvis dette sker, bør den afledte klasse tilsidesætte baseklasseens bortskaffelsesmetode for at bortskaffe den afledte klasses ressourcer. Men husk at kalde basisklassens bortskaffelsesmetode.

Beskyttede tilsidesættelser Sub bortskaffes (ByVal bortskaffes som boolsk) Hvis ikke Me.disposed derefter. Hvis du bortskaffer derefter. 'Føj din kode til gratis administrerede ressourcer. Afslut Hvis. 'Føj din kode til gratis uadministrerede ressourcer. Afslut Hvis. MyBase. Bortskaf (bortskaffes) Afslut under

Motivet kan være lidt overvældende. Formålet med forklaringen her er at "afmystificere", hvad der faktisk sker, fordi de fleste af de oplysninger, du kan finde, ikke fortæller dig!

instagram story viewer