In dem Artikel, Coding New Instances of Objects, schrieb ich über die verschiedenen Möglichkeiten, die Neu Instanzen von Objekten können erstellt werden. Das gegenteilige Problem, ein Objekt zu entsorgen, ist etwas, über das Sie sich in VB.NET nicht sehr oft Gedanken machen müssen. NET enthält eine Technologie namens Müllsammler (GC), die normalerweise alles hinter den Kulissen leise und effizient erledigt. Aber gelegentlich, normalerweise bei Verwendung von Dateistreams, SQL-Objekten oder Grafikobjekten (GDI +) (d. H., nicht verwaltete Ressourcen) müssen Sie möglicherweise die Kontrolle über die Anordnung von Objekten in Ihrem eigenen Code übernehmen.
So wie ein conStrukturgeber (der Neu Schlüsselwort) erstellt ein neues Objekt, a destructor 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 sich um eine Formel für Fehler handelt, 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 ist dies der Fall, nachdem ein Objekt den Gültigkeitsbereich verlassen hat veröffentlicht von der Common Language Runtime (CLR). Der GC zerstört Objekte, wenn die CLR mehr freien Speicher benötigt. Die Quintessenz ist also, dass Sie nicht vorhersagen können, wann GC das Objekt tatsächlich zerstören wird.
(Welllll ... Das stimmt fast die ganze Zeit. Du kannst anrufen GC.Collect und einen Müllsammelzyklus erzwingen, aber die Behörden sagen allgemein, es ist ein Schlecht Idee und völlig unnötig.)
Zum Beispiel, wenn Ihr Code ein erstellt hat Kunde Objekt, es scheint, dass dieser Code es wieder zerstören wird.
Aber das tut es nicht. (Das Festlegen eines Objekts auf "Nothing" wird häufig als "Nothing" bezeichnet, Dereferenzierung das Objekt.) Eigentlich bedeutet es nur, dass die Variable nicht mehr mit einem Objekt verknüpft ist. Zu einem späteren Zeitpunkt wird der GC feststellen, dass das Objekt für die Zerstörung verfügbar ist.
Übrigens ist für verwaltete Objekte nichts davon wirklich notwendig. Ein Objekt wie ein Button bietet zwar eine Dispose-Methode, muss jedoch nicht verwendet werden, was nur wenige Benutzer tun. Beispielsweise werden Windows Forms-Komponenten einem Containerobjekt mit dem Namen hinzugefügt Komponenten. Wenn Sie ein Formular schließen, wird dessen Dispose-Methode automatisch aufgerufen. Normalerweise müssen Sie sich darüber nur Gedanken machen, 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, ist der Aufruf von Entsorgen Methode für das Objekt (falls eine verfügbar ist) und dereferenzieren Sie das Objekt.
Customer.Dispose () Customer = Nothing
Da GC ein verwaistes Objekt zerstört, ist dies nicht unbedingt erforderlich, unabhängig davon, ob Sie die Objektvariable auf Nothing setzen oder nicht.
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 a einzufügen Verwenden Block. Ein Using-Block garantiert die Entsorgung einer oder mehrerer solcher Ressourcen, wenn Ihr Code damit fertig ist.
In der GDI + -Serie ist die Verwenden Block wird häufig verwendet, um diese lästigen Grafikobjekte zu verwalten. Beispielsweise…
MyBrush als LinearGradientBrush verwenden _ = New LinearGradientBrush (_ Me.ClientRectangle, _ Color.Blue, Color.Red, _ LinearGradientMode.Horizontal) End Using
myBrush wird automatisch entsorgt, wenn das Ende des Blocks ausgeführt wird.
Der GC-Ansatz zur Speicherverwaltung ist eine große Veränderung gegenüber dem 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, sodass der interne Zähler ausgeschaltet war. (Da in diesem Fall der Speicher gebunden war und anderen Objekten nicht zur Verfügung stand, wurde dies als "Speicherverlust" bezeichnet.) Stattdessen prüft GC, ob ein Objekt referenziert wird, und zerstört es, wenn keine weiteren Referenzen 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 befassen wir uns mit der IDisposable-Schnittstelle… der Schnittstelle, die Sie verwenden müssen, um nicht verwaltete Objekte in Ihrem eigenen Code zu entsorgen.
Wenn Sie Ihr eigenes Objekt codieren, das nicht verwaltete Ressourcen verwendet, sollten Sie das verwenden IDisposable Schnittstelle für das Objekt. 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):
Die Klasse ResourceClass implementiert IDisposable, um redundante Aufrufe zu erkennen. 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 'Geben Sie Ihren eigenen Status frei (nicht verwaltete Objekte). 'Setzen Sie große Felder auf null. End If Me.disposed = True End Sub #Region "IDisposable Support" 'Dieser Code wurde von Visual Basic hinzugefügt, um das Einwegmuster korrekt zu implementieren. Public Sub Dispose () Implementiert IDisposable.Dispose 'Diesen Code nicht ändern. 'Bereinigungscode in' Dispose (ByVal disposing As Boolean) eingeben. Dispose (True) GC.SuppressFinalize (Me) End Sub Geschützte Überschreibungen Sub Finalize () 'Diesen Code nicht ändern. 'Bereinigungscode in' Dispose (ByVal disposing As Boolean) eingeben. Dispose (False) MyBase.Finalize () End Sub #End Region End Class
Entsorgen ist fast ein "erzwungenes" Entwicklerentwurfsmuster in .NET. Es gibt wirklich nur einen richtigen Weg, und das ist es. Sie könnten denken, dieser Code macht etwas Magisches. Das tut es nicht.
Beachten Sie zunächst, dass die interne Flagge entsorgt Schließen Sie einfach das Ganze kurz, damit Sie anrufen können Entsorgen so oft du willst.
Der Code…
GC.SuppressFinalize (Me)
… Macht Ihren Code effizienter, indem Sie dem GC mitteilen, dass das Objekt bereits entsorgt wurde (eine im Hinblick auf die Ausführungszyklen „teure“ Operation). Finalize ist Protected, da GC es automatisch aufruft, wenn ein Objekt zerstört wird. Sie sollten niemals Finalize anrufen. Der Boolesche Entsorgen teilt dem Code mit, ob Ihr Code die Entsorgung des Objekts initiiert hat (True) oder ob der GC dies getan hat (als Teil des Finalisieren sub. Beachten Sie, dass der einzige Code, der den Booleschen Wert verwendet Entsorgen ist:
Bei Entsorgung Dann 'Anderen Zustand freigeben (verwaltete Objekte). End If
Wenn Sie ein Objekt entsorgen, müssen alle seine Ressourcen entsorgt werden. Wenn der CLR-Garbage Collector ein Objekt entsorgt, 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 Stellen 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 (disposing) -Methode der Basisklasse überschreiben, um die Ressourcen der abgeleiteten Klasse zu entsorgen. Denken Sie jedoch daran, die Dispose (disposing) -Methode der Basisklasse aufzurufen.
Geschützte Überschreibungen Sub Dispose (ByVal disposing As Boolean) If Not Me.disposed Then If disposing Then 'Fügen Sie Ihren Code hinzu, um verwaltete Ressourcen freizugeben. End If 'Fügen Sie Ihren Code hinzu, um nicht verwaltete Ressourcen freizugeben. End If MyBase.Dispose (Entsorgen) End Sub
Das Thema kann leicht überwältigend sein. Der Zweck dieser Erklärung besteht darin, die tatsächlichen Vorgänge zu "entmystifizieren", da die meisten Informationen, die Sie finden können, keine Informationen enthalten!