2009-12-28 7 views
20

Jon Skeet made a comment (via Twitter) auf meine SOApiDotNet Code (eine .NET-Bibliothek für den Pre-Alpha-Stack-Überlauf API):C#: "Verwenden von" Statements mit HttpWebRequests/HttpWebResponses

@ maximz2005 Eine Sache, die ich bemerkt habe nur von der Quelle schnell durchsuchen: Sie nicht von WebResponses entsorgt werden. "using" -Anweisungen FTW.

Er zeigt an, dass ich diese Websitzungen in "using" -Anweisungen einbinden muss. Allerdings habe ich eine Frage dazu: sollte ich die ganze Sache wickeln, beginnend mit der HttpWebRequest, oder sollte ich die WebRequest außerhalb der "mit" -Anweisung erstellen und dann die Antwort innerhalb wrap? Ich habe das Gefühl, dass der Unterschied darin besteht, dass in dem ersten beide Objekte entsorgt würden - ist das korrekt?

Vielen Dank im Voraus.

Antwort

42

HttpWebRequest schreiben selbst ist nicht Einweg im Gegensatz zu HttpWebResponse. Sie sollten die verfügbaren Ressourcen einbetten, um eine frühzeitige und gezielte Bereinigung zu ermöglichen. Korrekt implementiert IDisposable Muster ermöglicht mehrere Aufrufe an Dispose ohne Probleme, so dass auch die äußere Verwendung der Anweisung umschließt Ressource, die während ihrer eigenen Verfügung interne Anweisung Anweisung Ressource ist es noch in Ordnung.

Codebeispiel

var request = (HttpWebRequest)WebRequest.Create("example.com"); 
using (var response = (HttpWebResponse)request.GetResponse()) 
{ 
    // Code here 
} 
+0

So sollte ich ..Anfrage außerhalb, oder was? –

+2

Ja, das bedeutet, dass Sie eine var request = (HttpWebRequest) WebRequest.Create ("http://example.com"); mit (var Antwort = (HttpWebResponse) request.GetResponse()) { // Code hier } –

+1

@Dzmitry, @Benjamin. Ich habe Benjamins Codebeispiel zu Ihrer Antwort hinzugefügt. –

6

Alles, was in einem using() {} -Block (also innerhalb der ersten Klammern) eingeschlossen ist, wird beim Verlassen des Bereichs entsorgt.

Ich habe Ihre Bibliothek bisher nicht benutzt (scheint nett zu sein), aber ich würde argumentieren, dass Sie jedes IDisposable, das Sie erstellen (= dafür verantwortlich sind), explizit entsorgen und nicht zu einem Anrufer zurückkehren sollten.

Nebenbei bemerkt, da ich eine Menge Leute mit mehreren Dinge gesehen haben, kämpfen zu entsorgen: Statt

using (var foo = SomeIDisposable) { 
    using (var bar = SomeOtherIDisposable) { 
    } 
} 

die viel vertikalen Raum braucht man

using (var foo = SomeIDisposable) 
using (var bar = SomeOtherIDisposable) { 
} 
+0

Ihr zweiter Absatz (der richtig ist, glaube ich) widerspricht dem ersten. Wenn alles innerhalb des using-Blocks angeordnet ist, benötigen Sie die innere using-Anweisung nicht. – Tomas

+0

Siehe meinen aktualisierten Beitrag: Alles innerhalb der Verwendung von (...) ist entsorgt, wenn Sie den folgenden Block (diesen Teil: {...}) –

1

Um Speicherlecks zu verhindern, dass Sie Entsorgen auf jedem Objekt aufrufen sollte, die IDisposable implementiert. Sie können sicherstellen, dass die Dispose-Methode mit dem Schlüsselwort using (kein Wortspiel beabsichtigt) aufgerufen wird, da es sich nur um einen syntaktischen Zucker für try-finally-Block handelt.