2009-12-28 5 views
20

Jon Skeet made a comment (via Twitter) en mi SOApiDotNet código (una biblioteca .NET para la API de pre-alfa desbordamiento de pila):C#: "El uso de" Declaraciones con HttpWebRequests/HttpWebResponses

@ maximz2005 Una cosa que he notado simplemente navegando por la fuente rápidamente: que no desecha (sic) de WebResponses. declaraciones "usando" FTW.

Indica que tengo que ajustar estas sesiones web en las instrucciones "using". Sin embargo, tengo una pregunta sobre esto: ¿debo envolver todo, comenzando con HttpWebRequest, o debería crear la WebRequest fuera de la instrucción "using" y luego ajustar la respuesta dentro de? Tengo la sensación de que la diferencia es que, en el primer caso, se eliminarían ambos objetos, ¿es correcto?

Gracias de antemano.

Respuesta

42

HttpWebRequest en sí mismo no es desechable a diferencia de HttpWebResponse. Debe envolver los recursos desechables con el uso para permitir una limpieza temprana y determinada. Correctamente implementado, el patrón IDisposable permite múltiples llamadas a Dispose sin ningún problema, por lo que incluso la declaración de uso externa ajusta el recurso que, en el caso de que disponga de ella, dispone de un recurso de declaración interno, todavía está bien.

ejemplo Código

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

Entonces, ¿debo declarar ... Solicitud fuera, o qué? –

+2

Sí, eso significa que haría una petición var = (HttpWebRequest) WebRequest.Create ("http://example.com"); usando (var response = (HttpWebResponse) request.GetResponse()) { // Codifica aquí } –

+1

@Dzmitry, @Benjamin. Añadí el ejemplo de código de Benjamin a tu respuesta. –

6

Todo lo que se envuelve en un bloque using() {} (es decir, dentro de los primeros corchetes) se elimina cuando sale del alcance.

No he utilizado su biblioteca hasta el momento (aunque parece agradable), pero me gustaría argumentar que debe disponer explícitamente de todos los IDisposable que cree (= son responsables de) y no devolver a la persona que llama.

Una nota al margen, ya que he visto un montón de personas que luchan con varias cosas para disponer: En lugar de

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

que necesita una gran cantidad de espacio vertical puede escribir

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

Su segundo párrafo (que es correcto, creo) contradice al primero. Si se elimina todo lo que está dentro del bloque de uso, no necesitaría la instrucción de uso interno. – Tomas

+0

Ver mi publicación actualizada: todo lo que está dentro del uso (...) se elimina cuando abandona el siguiente bloque (esta parte: {...}) –

1

Con el fin de evitar pérdidas de memoria que debe llamar a Dispose en cada objeto que implementa IDisposable. Puedes asegurarte de que el método Dispose in llamado usando la palabra clave using (sin juego de palabras) ya que es solo un azúcar sintáctico para el bloque try-finally.

Cuestiones relacionadas