2010-07-09 6 views
5

Ich habe eine dumme Frage, aber ich möchte die Gemeinschaft hier hören.Entsorgung von Ressourcen in .NET

So, hier ist mein Code:

using (FtpWebResponse response = (FtpWebResponse)request.GetResponse()) 
{ 
     return true; 
} 

Meine Frage, ist es anders als:

(FtpWebResponse)request.GetResponse(); 
return true; 

Welche ist besser im Allgemeinen? welche in Bezug auf GC und warum?

+0

Ich denke, dass Sie den Punkt hier verpasst haben: Wie Sie auf der zweiten Option sehen können, sollte ich es so schreiben: request.GetResponse(); Rückkehr wahr; Wie Sie sehen können, ist es mir egal, was in der GetResponse zurückkehrt und es vollständig ignorieren. In Bezug auf die Verwendung Funktionalität, ich bin mir völlig bewusst, ich war mir nicht sicher, ob es einen zusätzlichen Vorteil des Hinzufügens der Verwendung hier gibt, können Sie nicht einmal die Antwort kümmern. ich hoffe, ich habe es geklärt. –

+4

@Or A: Egal, ob Sie sich für die Antwort interessieren oder nicht, Sie rufen immer noch 'GetResponse' an, was bedeutet, dass das zurückgegebene Objekt noch entsorgt werden muss. (Und das empfohlene Muster dafür wäre normalerweise ein "using" -Block.) – LukeH

+0

@LukeH: In diesem seltsamen Kontext ist es wahrscheinlich in Ordnung, eine '.Dispose(); –

Antwort

11

Die erste ist besser, aber nicht in Bezug auf GC. WebResponse implementiert IDisposable, weil es Ressourcen hat, die freigegeben werden müssen, wie Netzwerkverbindungen, Speicher Streams usw. IDisposable ist vorhanden, weil Sie, als der Verbraucher, wissen, wenn Sie mit dem Objekt fertig sind und rufen Sie an notify die Klasse, du bist fertig damit, und es ist frei, nach sich selbst aufzuräumen.

Die using Muster wirklich ruft nur Dispose unter der Haube. Z.B. Ihr erstes Beispiel ist eigentlich zu sein, dies zusammengestellt:

FtpWebResponse response = (FtpWebResponse)request.GetResponse() 
try 
{ 
} 
finally 
{ 
    ((IDisposable)response).Dispose(); 
} 
return true; 

Diese vom Garbage Collector getrennt ist. Eine Klasse könnte auch Ressourcen in der Finalizerthread aufzuräumen, die von GC aufgerufen wird, aber man sollte nicht darauf verlassen aus zwei Gründen geschehen:

  1. es sehr lange dauern kann, bis GC schließlich herum kommt, die bedeutet, dass diese Ressourcen dort sitzen und ohne guten Grund verbraucht werden.
  2. Es ist nicht wirklich Ressourcen bereinigen könnte in der Finalizerthread ohnehin
+0

Wie Sie in meinen Kommentaren sehen können, spielt die Antwort hier keine Rolle. Ich ignoriere es vollständig. –

+6

@Or A: Egal, ob Sie sich für die Antwort interessieren oder nicht, Sie rufen immer noch 'GetResponse' an, was bedeutet, dass das zurückgegebene Objekt noch entsorgt werden muss. (Und das empfohlene Muster wäre normalerweise ein 'using' Block.) – LukeH

7

Die erste ist besser.

Der Unterschied besteht darin, dass die Anweisung using das Objekt, das darin eingebettet ist, abruft. Es wird die gehaltenen Ressourcen korrekt entsorgen.

Von MSDN, die using-Anweisung:

Bietet eine bequeme Syntax, die die korrekte Verwendung von IDisposable Objekte gewährleistet.

+0

Warum der Downvote? – Oded

+0

Keine Ahnung, also habe ich upcountert um zu kompensieren. –

+0

Es war wahrscheinlich von jemandem, der immer noch denkt, dass "Dispose" optional ist. Hier ist ein +1 zu kompensieren ... obwohl Steven es bereits getan hat. –

4

Ich schätze, dass Sie in der Antwort nicht interessiert sind. Das Antwortobjekt wurde jedoch erstellt, initialisiert und an Ihren Code zurückgegeben, unabhängig davon, ob Sie es wollten oder nicht. Wenn Sie es nicht entsorgen, wird es Ressourcen verbrauchen, bis der GC es schließlich fertig bringt.

2

Ich stimme mit dem, was andere gesagt haben, aber wenn Sie eine solche Hass für die Verwendung von() Syntax haben, könnten Sie tun:

((IDisposable)request.GetResponse()).Dispose(); 
return true; 
+1

Ja, das ist in Ordnung, obwohl' using' in fast allen anderen Fällen besser ist. –

+0

Und der Grund 'using' ist besser, ist, dass es sicherstellt, dass Dispose aufgerufen wird, selbst wenn eine Ausnahme auftritt. – AaronLS

+0

Verwenden ist besser, wenn zwischen dem Zeitpunkt der Erstellung des Objekts und der Zeit, zu der es erstellt wird, eine Ausnahme auftreten konnte. Die einzige Möglichkeit, die im obigen Code auftreten könnte, wäre, wenn GetResponse irgendwie etwas anderes als ein iDisposable zurückgibt, in welchem ​​Fall Using sowieso nichts helfen würde. – supercat

1

Die GC nicht über etwas anderes als Speicher schert, wenn Sie also habe viel Speicher und konsumiere nicht viel davon, es könnte sehr lange dauern, bis es einen GC macht. Während dieser ganzen Zeit bleiben die nicht verwalteten Ressourcen, wie Netzwerkverbindungen, Dateihandles, Datenbankverbindungen, Grafikhandles usw., durch die Objekte, die darauf warten, erfasst zu werden, gebunden. Dies kann dazu führen, dass Ihnen diese Ressourcen ausgehen und der GC wird sich nicht mehr bewusst sein, da nicht verwaltete Ressourcen nicht überwacht werden.

Wenn Sie also Ihren Code in eine Schleife einfügen und ihn aufrufen, ohne Dispose aufzurufen, verschlechtert sich möglicherweise die Leistung (Prozesse, die um knappe Ressourcen kämpfen) oder eine Ausnahme aufgrund fehlender nicht verwalteter Ressourcen . Es hängt vom Kontext ab, wie es aufgerufen wird und wie Sie andere verwandte Objekte erstellen. Anstatt jede Situation zu analysieren, ist es immer am sichersten, Dispose aufzurufen, sobald Sie mit der Instanz fertig sind.

Es stimmt, dass Dispose vom GC für ein Objekt aufgerufen wird, das den Gültigkeitsbereich verlassen hat oder nicht mehr referenziert wird, aber dies ist indeterministisch. Da sie indeterministisch sind, könnten Sie unterschiedliche Ergebnisse sehen, wie schnell Ressourcen beim Testen gegen die Produktion frei werden und zu zufälligen Ausnahmen führen, wenn Ressourcen nicht zugewiesen werden, wenn sie verbraucht sind. Wenn Sie zwischen konsistentem deterministischem Verhalten Ihrer Anwendung und indeterministischem Verhalten wählen könnten, würden Sie wahrscheinlich deterministisch sein wollen, es sei denn, Sie versuchen vielleicht, Ihre Tester zu verwirren.