Computerwissenschaften

Objekte in Visual Basic entsorgen

In dem Artikel Codieren neuer Instanzen von Objekten habe ich über die verschiedenen Möglichkeiten geschrieben, wie neue Instanzen von Objekten erstellt werden können. Das entgegengesetzte Problem, das Entsorgen eines Objekts, ist etwas, über das Sie sich in VB.NET nicht oft Sorgen machen müssen. .NET enthält eine Technologie namens Garbage Collector ( GC ), die normalerweise alles hinter den Kulissen still und effizient erledigt. Gelegentlich, normalerweise bei der Verwendung von Dateistreams, SQL-Objekten oder Grafikobjekten (GDI +) (dh nicht verwalteten Ressourcen ), müssen Sie möglicherweise die Kontrolle über das Entsorgen von Objekten in Ihrem eigenen Code übernehmen.

 

Zunächst einige Hintergrundinformationen

So wie ein con structor (das neue Schlüsselwort) ein neues schafft Objekt. ein de structor ist eine Methode , die aufgerufen wird , wenn ein Objekt zerstört wird. Aber da ist ein Fang. Die Leute, die .NET erstellt haben, haben erkannt, dass es eine Formel für Fehler ist, wenn zwei verschiedene Codeteile tatsächlich ein Objekt zerstören können. Der .NET GC hat also tatsächlich die Kontrolle und ist normalerweise der einzige Code, der die Instanz des Objekts zerstören kann. Der GC zerstört ein Objekt, wenn er sich dazu entscheidet und nicht vorher. Normalerweise wird ein Objekt, nachdem es den Gültigkeitsbereich verlassen hat, von der Common Language Runtime (CLR) freigegeben . Der GC zerstört Objekte, wenn die CLR mehr freien Speicher benötigt. Unter dem Strich können Sie also nicht vorhersagen, wann GC das Objekt tatsächlich zerstören wird.

(Welllll … Das stimmt fast die ganze Zeit. Sie können anrufen GC.Collect und eine Kraft , die Garbage Collection – Zyklus. sondern Behörden allgemein sagen , dass es eine schlechte Idee und völlig unnötig.)

Wenn Ihr Code beispielsweise ein Kundenobjekt erstellt hat , scheint es, dass dieser Code es erneut zerstört.

 

Kunde=nichts

Aber das tut es nicht. (Das Setzen eines Objekts auf „Nichts“ wird häufig als “ Dereferenzieren des Objekts“ bezeichnet.) Tatsächlich bedeutet dies nur, dass die Variable keinem Objekt mehr zugeordnet ist. Einige Zeit später wird der GC feststellen, dass das Objekt zur Zerstörung verfügbar ist.

Übrigens ist für verwaltete Objekte nichts davon wirklich notwendig. Obwohl ein Objekt wie ein Button eine Dispose-Methode bietet, ist es nicht erforderlich, es zu verwenden, und nur wenige Menschen tun dies. Beispielsweise werden Windows Forms-Komponenten zu einem Containerobjekt mit dem Namen “ Komponenten“ hinzugefügt . Wenn Sie ein Formular schließen, wird seine Dispose-Methode automatisch aufgerufen. Normalerweise müssen Sie sich nur darum kümmern, wenn Sie nicht verwaltete Objekte verwenden, und selbst dann nur, um Ihr Programm zu optimieren.

Die empfohlene Methode zum Freigeben von Ressourcen, die möglicherweise von einem Objekt gehalten werden, besteht darin, die Dispose- Methode für das Objekt aufzurufen (sofern verfügbar) und das Objekt dann dereferenzieren.

 Customer.Dispose()
Customer=Nothing 

Da GC ein verwaistes Objekt zerstört, unabhängig davon, ob Sie die Objektvariable auf Nothing setzen oder nicht, ist dies nicht unbedingt erforderlich.

Eine andere empfohlene Methode, um sicherzustellen, dass Objekte zerstört werden, wenn sie nicht mehr benötigt werden, besteht darin, den Code, der ein Objekt verwendet, in einen Using- Block einzufügen . Ein Using-Block garantiert die Entsorgung einer oder mehrerer solcher Ressourcen, wenn Ihr Code damit fertig ist.

In der GDI + -Serie wird der Using- Block häufig zum Verwalten dieser lästigen Grafikobjekte verwendet. Zum Beispiel …

 Using myBrush As LinearGradientBrush _
= New LinearGradientBrush( _
Me.ClientRectangle, _
Color.Blue, Color.Red, _
LinearGradientMode.Horizontal)
<... more code ...>
End Using 

myBrush wird automatisch entsorgt, wenn das Ende des Blocks ausgeführt wird.

Der GC-Ansatz zur Speicherverwaltung ist eine große Änderung gegenüber VB6. COM-Objekte (von VB6 verwendet) wurden zerstört, als ein interner Referenzzähler Null erreichte. Aber es war zu leicht, einen Fehler zu machen, so dass der interne Zähler ausgeschaltet war. (Da der Speicher gebunden war und zu diesem Zeitpunkt nicht für andere Objekte verfügbar war, wurde dies als „Speicherverlust“ bezeichnet.) Stattdessen prüft GC tatsächlich, ob etwas auf ein Objekt verweist, und zerstört es, wenn keine Referenzen mehr vorhanden sind. Der GC-Ansatz hat eine gute Geschichte in Sprachen wie Java und ist eine der großen Verbesserungen in .NET.

Auf der nächsten Seite sehen wir uns die IDisposable-Schnittstelle an … die Schnittstelle, die verwendet werden soll, wenn Sie nicht verwaltete Objekte in Ihrem eigenen Code entsorgen müssen.

Wenn Sie Ihr eigenes Objekt codieren, das nicht verwaltete Ressourcen verwendet, sollten Sie die IDisposable- Schnittstelle für das Objekt verwenden. Microsoft macht dies einfach, indem es ein Code-Snippet einfügt, das das richtige Muster für Sie erstellt.

——–
Klicken Sie hier, um die Abbildung anzuzeigen.
Klicken Sie in Ihrem Browser auf die Schaltfläche Zurück, um zurückzukehren.
——–

Der hinzugefügte Code sieht folgendermaßen aus (VB.NET 2008):

 Class ResourceClass Implements IDisposable ' To detect redundant calls Private disposed As Boolean=False ' IDisposable Protected Overridable Sub Dispose( _ByVal disposing As Boolean)If Not Me.disposed Then   If disposing Then   ' Free other state (managed objects).   End If   ' Free your own state (unmanaged objects).   ' Set large fields to null.End IfMe.disposed=True End Sub
#Region " IDisposable Support " ' This code added by Visual Basic to ' correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose' Do not change this code.' Put cleanup code in' Dispose(ByVal disposing As Boolean) above.Dispose(True)GC.SuppressFinalize(Me) End Sub Protected Overrides Sub Finalize()' Do not change this code.' Put cleanup code in' Dispose(ByVal disposing As Boolean) above.Dispose(False)MyBase.Finalize() End Sub
#End Region
End Class 

Dispose ist in .NET fast ein „erzwungenes“ Entwicklerentwurfsmuster. Es gibt wirklich nur einen richtigen Weg, und das ist es. Sie könnten denken, dieser Code macht etwas Magisches. Das tut es nicht.

Zunächst ist zu beachten , dass das interne Flag angeordnet einfach Kurzschlüssen , die ganze Sache so können Sie anrufen Dispose (Entsorgung) so oft wie Sie möchten.

Der Code …

 GC.SuppressFinalize(Me) 

… macht Ihren Code effizienter, indem Sie dem GC mitteilen, dass das Objekt bereits entsorgt wurde (eine „teure“ Operation in Bezug auf Ausführungszyklen). Finalize ist geschützt, da GC es automatisch aufruft, wenn ein Objekt zerstört wird. Sie sollten Finalize niemals aufrufen. Die boolesche Disposition teilt dem Code mit, ob Ihr Code die Entsorgung des Objekts initiiert hat (True) oder ob der GC dies getan hat (als Teil des Unterabschnitts Finalize . Beachten Sie, dass der einzige Code, der die boolesche Disposition verwendet, Folgendes ist:

 If disposing Then ' Free other state (managed objects).
End If 

Wenn Sie ein Objekt entsorgen, müssen alle seine Ressourcen entsorgt werden. Wenn der CLR- Garbage Collector über ein Objekt verfügt, müssen nur die nicht verwalteten Ressourcen entsorgt werden, da der Garbage Collector sich automatisch um die verwalteten Ressourcen kümmert.

Die Idee hinter diesem Code-Snippet ist, dass Sie Code hinzufügen, um verwaltete und nicht verwaltete Objekte an den angegebenen Speicherorten zu verwalten.

Wenn Sie eine Klasse von einer Basisklasse ableiten , die IDisposable implementiert, müssen Sie keine der Basismethoden überschreiben, es sei denn, Sie verwenden andere Ressourcen, die ebenfalls entsorgt werden müssen. In diesem Fall sollte die abgeleitete Klasse die Dispose-Methode (Dispositionsmethode) der Basisklasse überschreiben, um die Ressourcen der abgeleiteten Klasse zu entsorgen. Denken Sie jedoch daran, die Dispose-Methode (Dispositionsmethode) der Basisklasse aufzurufen.

 Protected Overrides Sub Dispose(ByVal disposing As Boolean) If Not Me.disposed ThenIf disposing Then' Add your code to free managed resources.End If' Add your code to free unmanaged resources. End If MyBase.Dispose(disposing)
End Sub 

Das Thema kann etwas überwältigend sein. Der Zweck der Erklärung hier ist, zu „entmystifizieren“, was tatsächlich passiert, weil die meisten Informationen, die Sie finden können, Ihnen nichts sagen!

Similar Posts

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.