2009-07-20 6 views
2

ich einige VB .NET-Code vor kurzem sah wie folgt aus:Führt die Zuweisung zu Nothing dazu, dass Dispose aufgerufen wird?

Dim service = ... 
Try 
    ... 
    service.Close() 
Finally 
    service = Nothing 
End Try 

nichts tut Zuordnung etwas zu warten zu tun? Wenn es sich um ein Garbage-Collection-Problem handelt, gehe ich davon aus, dass, wenn "Dienst" den Gültigkeitsbereich überschritten hat, das referenzierte Objekt als Garbage Collected erfasst und die dispose-Methode für das Objekt aufgerufen wird.

Es scheint mir, dass die Zuweisung dieser Variablen nichts wirklich tun kann, da es einen anderen Verweis auf das Objekt geben könnte, so dass die Referenz zählt haev, um trotzdem überprüft werden.

+0

@Larry: Beachten Sie, dass das Wort "Dispose" nie auf der Seite angezeigt wird, mit der ftank99 verknüpft ist. –

Antwort

0

Sieht aus wie die Antwort der Antwort auf dieses Thema liegt: Loops and Garbage Collection

+0

Danke! Es ist, was alle meine Instinkte und Intuitionen mir gesagt haben .. aber es tut mir nie weh zu überprüfen :) –

+0

@ftank: nicht ganz; Das Objekt implementiert IDisposable nicht, wodurch eine weitere Dimension hinzugefügt wird. –

+0

Diese Antwort ist nicht korrekt. –

3

NO!

Sie sehen alten VB6-Code, bei dem das Zuweisen von Nothing die Verweisanzahl für COM-Objekte reduzierte.

+0

Danke! Ich schaue eigentlich auf VB .NET-Code, aber ich denke, die Person, die mir geraten hat, dies zu tun, hat diese Gewohnheit aus VB6-Programmierpraktiken entwickelt. Das erklärt mir, warum man einer Variablen gar nichts zuordnet - nachdem ich jahrelang gc verwendet und nur kurz referenziert habe, ist mir die Referenzzählmöglichkeit gar nicht erst aufgefallen. –

4

Es gibt nur die Referenz frei, was bedeuten kann, dass das Objekt für die Garbage Collection verfügbar ist (es könnte immer noch andere Variablen geben, die dasselbe Objekt referenzieren). Wenn das Objekt IDisposable implementiert, müssen Sie explizit Dispose aufrufen, andernfalls haben Sie möglicherweise ein Ressourcenleck.

+0

Nun, kein Speicherleck. Nur ein Ressourcenleck. –

+0

@John: so wahr; wurde schlampig mit Begriffen dort. Korrigiert den Beitrag. Danke: o) –

1

Assigning NULL zu einer Referenz in .NET hilft nicht, das Objekt zu bereinigen. Es könnte dem Müllsammler helfen, in einigen Fällen etwas schneller zu laufen, aber das ist überhaupt nicht wichtig. Es ruft auch nicht auf (entweder im Umgang mit einem Disposable)

Ich liebe NULL anyways, explizit anzugeben, dass ich dieses andere Objekt nicht mehr verwenden werde. Es hat also viel mehr mit dem Abfangen von Fehlern zu tun (Sie erhalten eine Nullreferenz-Ausnahme, anstatt möglicherweise in ein anderes Objekt zu rufen - was scheitern oder sogar einige Nebenwirkungen erzeugen könnte.)

Also NULL nach dem Schließen eines anderen Objekts zuweisen (Datei oder was auch immer) ist eine "Code Sauberkeit" Sache, die das Debuggen erleichtert, es ist keine Hilfe für den Garbage Collector (außer in einigen wirklich seltsamen Fällen - aber wenn Sie sich darum kümmern müssen, werden Sie mehr über den Garbage Collector als wissen du wolltest schon immer wissen ...)

+0

Die Begrenzung des Umfangs einer Variablen ist noch besser, um Fehler zu vermeiden, da Sie die Variable nicht erreichen können. Auf diese Weise gibt Ihnen der Compiler den Fehler sofort, anstatt ihn zur Laufzeit zu bekommen. – Guffa

+0

Guffa, das ist definitiv richtig. Ich verwende diese Technik ausschließlich für Felder in einer Klasse. In C++/C# verwende ich streng Scoping (und in C++ können Sie den Bereich auch für die Kontrolle der Erstellung/Zerstörung von Objekten, google RAII für weitere Informationen verwenden - etwas, wo C#/IDisposable ist nur ein schwacher Ersatz für.) – froh42

2

In den meisten Situationen macht die Zuordnung von null (Nothing) zu einer Referenz keinen Unterschied zur Garbage Collection was auch immer.

Der Garbage Collector interessiert sich nicht für den Umfang, es kümmert nur die Verwendung. Nach dem Punkt im Code, an dem das Objekt das letzte Mal verwendet wurde, weiß der Garbage Collector, dass er es erfassen kann, weil es nicht mehr verwendet wird.

Das Zuweisen von null zum Verweis zählt nicht als Verwendung des Objekts, daher liegt der letzte Verwendungspunkt vor diesem Code. Wenn Sie die Referenz löschen, hat der Garbage Collector das Objekt möglicherweise bereits erfasst.

(Im Debug-Modus wird die Verwendung einer Variablen auf ihren Gültigkeitsbereich erweitert, sodass der Debugger den Wert der Variablen im gesamten Gültigkeitsbereich anzeigen kann.)

+0

Sie sind für lokale Variablen korrekt. Die ursprüngliche Frage * sieht * wie eine lokale Variable aus. – MarkJ

1

Wie jeder hat schon gesagt, nichts Einstellung nicht Garbage Collection nicht erzwingen, wenn Sie GC erzwingen wollen, dann würden Sie viel besser sein, die mit ke Wort

Using objA As A = New A() 
     objA.DoSomething() 
    End Using 

Sie noch nicht verwenden muss auf nichts festgelegt werden, da das Ende mit der Garbage-Auflistung angibt, dass das Objekt nicht mehr verwendet werden soll

0

Es ist wichtig, in .net (oder Java) eine Variable, ein Feld oder einen anderen Speicherort des Klassentyps zu verstehen Foo hält keine Foo. Es enthält einen Verweis auf eine Foo. Ebenso hält List<Foo> nicht Foo s; es enthält Verweise auf Foo s. In vielen Fällen wird dem Programmierer eine Variable bekannt sein, die den einzigen erhaltenen Verweis auf eine bestimmte Foo enthält. Leider hat der Compiler kein allgemeines Mittel zu wissen, ob ein Speicherort die einzige erhaltene Referenz auf ein Objekt enthält oder ob es eine von vielen enthält. Die Hauptregel über IDisposable ist, dass Objekte, die IDisposable implementieren, gesagt werden sollen, dass sie nicht mehr zwischen dem Moment, in dem sie tatsächlich nicht mehr benötigt werden, und der Zeit, zu der alle Referenzen auf sie fallen, nicht mehr benötigt werden. Wenn ein Objekt nicht Dispose d ist und der Code die einzige vorhandene Referenz überschreiben soll (entweder durch Speichern von null oder durch Speichern einer Referenz auf etwas anderes), sollte das Objekt die Dispose-Methode aufgerufen haben. Wenn es einen anderen Verweis auf das Objekt gibt und die Inhaber dieser Referenzen erwarten, dass es weiter verwendet wird, sollte Dispose nicht aufgerufen werden. Da der Compiler nicht erkennen kann, welche Situation zutrifft, ruft er nicht Dispose auf, sondern überlässt das dem Programmierer (der hoffentlich eine bessere Vorstellung davon hat, ob er es nennen soll oder nicht).

Verwandte Themen