Cuándo llamar a WebResponse.Close()
-
19-09-2019 - |
Pregunta
WebResponse response;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 20000;
response = request.GetResponse();
request = (HttpWebRequest)WebRequest.Create(url2);
response = request.GetResponse();
}
catch(Exception ex)
{
//do something
}
finally
{
}
¿Dónde debería llamarse a Response.Close()?
¿Después de cada GetResponse() en el intento?
después del último GetResponse() en el intento, ¿una vez?
- en finalmente bloquear?
Solución
Ninguna de las anteriores. Usted debe utilizar un bloque using
:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 20000;
using (WebResponse response = request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
var result = reader.ReadToEnd();
// Do something with result
}
}
}
Un bloque using
se asegurará de que el método Dispose se llama, si hay o no es una excepción. Desechar va a hacer lo mismo que cerrar.
using (var d = new DisposableClass()){code;}
es equivalente a:
DisposableClass d = null;
try
{
d = new DisposableClass();
code;
}
finally
{
if (d != null)
((IDisposable)d).Dispose();
}
Otros consejos
Lo puso en el bloque finally. Según MSDN :
El bloque finally es útil para la limpieza de los recursos asignados en el bloque try, así como el funcionamiento de cualquier código que debe ejecutarse incluso si hay es una excepción. El control es siempre se pasa al bloque finally independientemente de cómo el bloque try.
Tenga en cuenta que los bloques de uso anidados no necesitan llaves, lo que mejora la legibilidad.Entonces el código de John Saunder podría escribirse:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 20000;
using (WebResponse response = request.GetResponse())
using (var stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
var result = reader.ReadToEnd();
// Do something with result
}
VS.NET entiende que dichos bloques anidados no necesitan sangría.Por cierto, tenga en cuenta que si conoce la codificación de la respuesta o va a ignorarla de todos modos, WebClient proporciona una API más simple: falta información del encabezado, por lo que la detección de codificación basada en encabezado (transferencia/texto) se vuelve imposible, pero por lo demás funciona bien.
Yo sugeriría el siguiente
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.google.com");
request.Timeout = 20000;
using (var response = request.GetResponse())
{
//Do something with response.
}
request = (HttpWebRequest)WebRequest.Create("http://www.bing.com");
using (var response = request.GetResponse())
{
//Do somehing with response
}
}
catch (Exception ex)
{
//do something
}
finally
{
}