2009-12-28 16 views
20

Jon Skeet made a comment (via Twitter) sul mio SOApiDotNet codice (una libreria .NET per l'API pre-alpha Stack Overflow):C#: "Uso di" istruzioni con HttpWebRequests/HttpWebResponses

@ maximz2005 Una cosa che ho notato basta sfogliare velocemente la fonte: non si dispone (sic) di WebResponses. "using" istruzioni FTW.

Indica che ho bisogno di avvolgere queste sessioni Web in istruzioni "using". Tuttavia, ho una domanda al riguardo: dovrei avvolgere il tutto, a partire da HttpWebRequest, o dovrei creare la richiesta Web al di fuori dell'istruzione "using" e quindi racchiudere la risposta all'interno di? Ho la sensazione che la differenza sia che, nel primo caso, entrambi gli oggetti sarebbero stati eliminati - è corretto?

Grazie in anticipo.

risposta

42

HttpWebRequest stesso non è usa e getta a differenza di HttpWebResponse. È necessario avvolgere le risorse usa e getta con l'utilizzo per consentire una pulizia anticipata e determinata. Correttamente implementato il modello IDisposable consente più chiamate a Dispose senza alcun problema, quindi anche l'istruzione using esterna racchiude la risorsa che durante la propria eliminazione dispone internamente utilizzando la risorsa di istruzione che è ancora ok.

Codice esempio

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

Quindi dovrei dichiarare .. Richiedere all'esterno o cosa? –

+2

Sì, ciò significa che dovresti eseguire una richiesta var = (HttpWebRequest) WebRequest.Create ("http://example.com"); utilizzando (var response = (HttpWebResponse) request.GetResponse()) { // Codice here } –

+1

@Dzmitry, @Benjamin. Ho aggiunto l'esempio di codice di Benjamin alla tua risposta. –

6

Tutto ciò che viene racchiuso in un blocco using() {} (ovvero all'interno delle prime parentesi) viene eliminato quando si lascia l'ambito.

Non ho ancora utilizzato la libreria (sembra carino), ma direi che è necessario disporre in modo esplicito di tutti gli ID che è possibile creare (= sono responsabili per) e non tornare a un chiamante.

Una nota a margine, da quando ho visto un sacco di persone alle prese con cose più a smaltire: invece di

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

che ha bisogno di un sacco di spazio verticale è possibile scrivere

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

Il tuo secondo paragrafo (che è corretto, credo) contraddice il primo. Se tutto ciò che è contenuto nel blocco using è eliminato, non è necessaria l'istruzione using interna. – Tomas

+0

Vedere il mio post aggiornato: Tutto l'interno dell'uso (...) viene eliminato quando si abbandona il seguente blocco (questa parte: {...}) –

1

Al fine di evitare perdite di memoria si dovrebbe chiamare Dispose su ogni oggetto che implementa IDisposable. Puoi assicurarti che il metodo Dispose sia chiamato usando la parola chiave using (nessun gioco di parole) poiché è solo uno zucchero sintattico per il blocco try-finally.