Когда вызвать WebResponse.Закрывать()


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
{
}

Где следует ответ.Закрыть() будет называться?

  • После каждого GetResponse () в try?

  • После последнего GetResponse() в try-once?

  • в последнем блоке?
4 13

4 ответа:

Ничего из вышеперечисленного. Вы должны использовать блок 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
        }
    }
}

Блок using гарантирует, что метод Dispose вызывается независимо от того, существует ли исключение. Dispose сделает то же самое, что и Close.

using (var d = new DisposableClass()){code;}

Эквивалентно:

DisposableClass d = null;
try
{
    d = new DisposableClass();
    code;
}
finally
{
    if (d != null)
        ((IDisposable)d).Dispose();
}

Поместите его в блок finally. Согласно MSDN:

Блок finally полезен для очистка любых ресурсов, выделенных в блок try, а также запуск любого код, который должен выполняться, даже если есть являться исключением. Контроль всегда есть прошел в последний блок, несмотря ни на что о том, как блок try выходит.

Обратите внимание, что вложенные блоки не нуждаются в фигурных скобках, что улучшает читаемость. Таким образом, код Джона Сандера можно записать так:

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 понимает, что такие вложенные блоки не нуждаются в отступах. Обратите внимание, кстати, что если вы знаете кодировку ответа или собираетесь игнорировать его в любом случае, WebClient предоставляет более простой API - недостающую информацию заголовка, поэтому обнаружение кодировки на основе заголовка (передача/текст) становится невозможным, но в остальном он работает нормально.

Я бы предложил следующее

        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
        {
        }