V članku Kodiranje novih primerkov predmetov sem pisal o različnih načinih, ki to Novo lahko ustvarijo primerke predmetov. Nasprotno težava pri odstranjevanju predmeta je nekaj, kar vam v VB.NET-u ne bo treba skrbeti. .NET vključuje tehnologijo, imenovano Zbiralec smeti (GC) ki običajno tiho in učinkovito poskrbi za vse zakulisje. Toda občasno, običajno pri uporabi datotečnih tokov, sql predmetov ali grafičnih (GDI +) predmetov (tj. neregulirani viri) boste morda morali prevzeti nadzor nad odstranjevanjem predmetov v lastni kodi.
Prvič, nekaj ozadja
Tako kot a konstruktor (the Novo ključna beseda) ustvari novo objekt, a destructor je metoda, ki se imenuje, ko se predmet uniči. Toda ulov je. Ljudje, ki so ustvarili .NET, so spoznali, da gre za formulo za napake, če lahko dva različna dela kode dejansko uničita predmet. Torej .NET GC dejansko nadzoruje in ponavadi je edina koda, ki lahko uniči primerek predmeta. GC uniči predmet, ko se odloči in ne prej. Običajno po tem, ko predmet zapusti obseg
izpuščen s skupnim jezikom izvajanja (CLR). GC uničuje predmete, ko CLR potrebuje več prostega pomnilnika. V bistvu torej ni mogoče predvideti, kdaj bo GC predmet dejansko uničil.(Welllll... To je res skoraj ves čas. Lahko pokličete GC.Collect in prisiliti a cikel zbiranja smetivendar oblasti na splošno pravijo, da je to slab ideja in popolnoma nepotrebna.)
Na primer, če je koda ustvarila Stranka objekta, morda se zdi, da ga bo ta koda znova uničila.
Stranka = nič
Ampak ne gre. (Če predmet postavite na Nič, se običajno imenuje, dereferenciranje predmet.) Pravzaprav to samo pomeni, da spremenljivka ni več povezana s predmetom. Čez nekaj časa bo GC opazil, da je predmet na voljo za uničenje.
Mimogrede, za upravljane predmete nič od tega res ni potrebno. Čeprav bo predmet, kot je gumb, ponujal način odstranjevanja, ga ni treba uporabljati in to počne le malo ljudi. Komponente sistema Windows Forms so na primer dodane v predmet z imenom sestavni deli. Ko zaprete obrazec, se samodejno pokliče metoda odstranjevanja. Običajno morate skrbeti le za kaj od tega, ko uporabljate nenadzorovane predmete, in celo samo za optimizacijo programa.
Priporočen način sprostitve vseh virov, ki bi jih lahko imel nek objekt, je klic Odložite metoda za objekt (če je na voljo) in nato odstranjevanje predmeta.
Stranka. Odložite () Stranka = nič
Ker bo GC uničil osirotel predmet, ne glede na to, ali spremenljivko predmeta nastavite na Nič, to res ni potrebno.
Drug priporočeni način, kako zagotoviti, da se predmeti uničijo, ko ne bodo več potrebni, je, da kodo, ki uporablja predmet, vstavimo v Uporaba blok. Uporaba bloka zagotavlja odstranjevanje enega ali več takih virov, ko je vaša koda z njimi končana.
V seriji GDI + je the Uporaba blok uporabljamo pogosto za upravljanje teh nadležnih grafičnih objektov. Na primer ...
Uporaba myBrush kot LinearGradientBrush _. = Nov LinearGradientBrush (_. Jaz. ClientRectangle, _. Barva. Modra, barva. Rdeča, _. LinearGradientMode. Vodoravno) <... ve kode ...> Končaj uporabo
myBrush se samodejno odstrani, ko se izvede konec bloka.
GC pristop k upravljanju spomina je velika sprememba od načina, kako je to naredil VB6. Predmeti COM (ki jih uporablja VB6) so bili uničeni, ko je notranji števec sklicev dosegel nič. Toda preveč enostavno je bilo narediti napako, da bi bil notranji števec izklopljen. (Ker je bil spomin povezan in ni bil na voljo drugim predmetom, ko se je to zgodilo, se je to imenovalo "uhajanje spomina".) Namesto tega GC dejansko preveri, ali se kaj nanaša na nek predmet in ga uniči, kadar ga ni več reference. GC pristop ima dobro zgodovino v jezikih, kot je Java, in je ena največjih izboljšav v .NET.
Na naslednji strani pogledamo vmesnik IDisposable... vmesnik, ki ga je treba uporabljati, ko morate nepredstavljene predmete odložiti v lastno kodo.
Če kodirate svoj lastni objekt, ki uporablja nenadzorovane vire, morate uporabiti ID-uporaben vmesnik za objekt. Microsoft to olajša tako, da vključi delček kode, ki ustvari pravi vzorec za vas.
Kliknite tukaj, če želite prikazati ilustracijo
Za vrnitev kliknite gumb Nazaj v brskalniku
Dodana koda izgleda tako (VB.NET 2008):
Razred ResourceClass. Izvaja ID-je za uporabo. „Za odkrivanje odvečnih klicev. Zasebno razporejen kot Boolean = False. „ID-je mogoče uporabiti. Zaščiteno prenašanje odlagališča (_. ByVal razpolaga kot Boolean) If Not Me.disposed nato. Če odstranite, potem. „Prosto drugo stanje (upravljani predmeti). Konec Če. „Osvobodite svoje stanje (nenadzorovani predmeti). "Velika polja nastavite na nič. Konec Če. Me.disposed = Res. Končni pod. #Region "IDisposable Support" "To kodo je Visual Basic dodal v. 'pravilno izvedite vzorec za enkratno uporabo. Javna podstran () Izvaja ID-je za uporabo. Odložite 'Ne spreminjajte te kode. "Vstavite kodo za čiščenje. „Odstranjevanje (ByVal odstranjuje kot Boolean) zgoraj. Odložite (True) GC.SuppressFinalize (Me) End Sub. Zaščitene preglasitve Sub Finalize () 'Ne spreminjajte te kode. "Vstavite kodo za čiščenje. „Odstranjevanje (ByVal odstranjuje kot Boolean) zgoraj. Odvrzite (napačno) MyBase. Dokončaj () Končni pod. #End Region. Končni razred
Odložite je skoraj "prisiljen" vzorec oblikovanja razvijalcev v .NET. Res je samo en pravilen način, in to je to. Morda mislite, da ta koda naredi nekaj čarobnega. Ne gre.
Najprej upoštevajte, da je notranja zastava odstranjeni preprosto kratek stik, da lahko pokličete Odstranjevanje (odstranjevanje) tako pogosto, kot želite.
Koda ...
GC.SuppressFinalize (Me)
... vašo kodo naredi bolj učinkovito s tem, da GC pove, da je bil predmet že odstranjen ("draga" operacija v smislu izvedbenih ciklov). Dokončno je zaščiteno, ker ga GC samodejno pokliče, ko se predmet uniči. Nikoli ne smete poklicati Finalize. Boolov razpolaganje pove kodo, ali je vaša koda sprožila odstranjevanje predmeta (True) ali je GC to storil (kot del Dokončaj pod. Upoštevajte, da je edina koda, ki uporablja Booleovo razpolaganje je:
Če odstranite, potem. „Prosto drugo stanje (upravljani predmeti). Konec Če
Ko odložite predmet, je treba odstraniti vse njegove vire. Ko CLR zbiralec smeti odstranjuje predmet, odstranjevati je treba le neurejene vire, ker zbiralec smeti samodejno skrbi za upravljane vire.
Ideja za ta delček kode je, da dodate kodo za skrb za upravljane in neupravljane predmete na navedenih mestih.
Ko izpeljete razred iz a osnovni razred ki izvaja IDisposable, vam ni treba preglasiti nobene osnovne metode, razen če uporabite druge vire, ki jih je prav tako treba odstraniti. Če se to zgodi, mora izpeljani razred nadomestiti metodo dispozicije (odstranjevanja) osnovnega razreda, da razpolaga z viri izpeljanega razreda. Ne pozabite pa poklicati metode dispozicije (odstranjevanja) osnovnega razreda.
Zaščiteno preglasovanje Sub-Dispose (ByVal odstranjuje kot logično), če ni Me.disposed. Če odstranite, potem. „Dodajte kodo v brezplačne upravljane vire. Konec Če. 'Dodajte kodo brezplačnim neupravljanim virom. Konec Če. MyBase. Odstranjevanje (odstranjevanje) Končni pod
Predmet je lahko nekoliko preobsežen. Namen pojasnila je "demistificirati", kaj se dejansko dogaja, ker večina informacij, ki jih najdete, vam ne pove!