2009-04-04 2 views

ответ

39

Если класс имеет особые требования по утилизации, было бы реализовано IDisposable. Поскольку он не реализует IDisposable, вы можете предположить, что вам ничего особенного не нужно делать.

+0

Существуют сценарии, в которых он не сразу выходит из сферы действия - особенно когда вы создаете несколько веб-запросов в течение короткого периода времени , Если вам нужно избавиться от него, просто добавьте его в 'IDisposable', а затем вызовите метод Dispose()' на нем. – 2015-12-30 11:13:29

+0

@mee это не имеет значения. 'HttpWebRequest' не реализует' IDisposable'. –

-2

HttpWebRequest не реализует IDisposable, поэтому он не требует утилизации. просто установите для объекта httprequest значение null, как только вы закончите с ним.

Надеется, что это помогает

+14

Зачем устанавливать значение null? Просто позволить ему выйти из области действия достаточно для GC, чтобы забрать его ..... –

3

httpwebRequest не реализует IDisposable, так как он может создавать Stream, который реализует IDisposable. Таким образом, вы не должны беспокоиться об утилизации.

Если вы обеспокоены тем не менее, вы можете использовать WebClient, который IDisposable:

using (WebClient c = new WebClient()) 
{ 
using (Stream stream = c.OpenRead(url)) 
{ 
// 
} 
} 
2

Вы можете использовать:

var webRequest = WebRequest.Create(ActionUrl) 
    using (var webResponse = webRequest.GetResponse()) 
    {} 

для вашей реализации. Когда я использовал класс WebRequest для запуска нескольких запросов за очень короткий промежуток времени, обертывание GetResponse() в блоке использования предотвращает зависание приложения.

14

У меня был аналогичный вопрос, и ответы здесь не дали мне необходимой информации. Поэтому, хотя есть приемлемый ответ, я собираюсь добавить то, что научился, чтобы помочь следующему парню.

1) Как упоминают другие ответы, вы можете использовать using для потоков, возвращаемых из HttpWebRequest/WebRequest. Это просто хорошее стандартное программирование на C#.

Но на самом деле это не касается вопроса OP (или моего), касающегося утилизации объекта HttpWebRequest.

2) Несмотря на то, что функция для получения HttpWebRequest называется «Создать», не существует соответствующего метода Destroy, Close, Dispose или любого другого механизма для освобождения ресурсов от созданного объекта.

Это в основном принятый в настоящее время ответ.

3) Но среди всех ответов есть смысл, что (кроме потоков) нет ничего важного, что можно было бы висели вокруг этого . будет закрыт. И это не совсем правильно.

Используя ProcMon, вы можете увидеть TCP Connect, TCP Send и TCP Receive, которые происходят при вызове GetResponse(). Это то, что я ожидал увидеть. Но когда происходит TCP Disconnect? Мое предположение заключалось в том, что это произойдет либо после того, как вы закончите получать ответ, либо в худшем случае, когда объект получит GC'ed. Но реальность более интересная.

Вместо этого соединение TCP остается активным ровно через 2 минуты после вызова. Моя первая мысль заключалась в том, сколько времени требуется GC, чтобы обойти это, но нет. Вы можете сидеть там в цикле GC.Collect() для этих 2 минут, и он не отпускает до тех пор, пока не начнется 2 минуты.Это держит соединение открытым как на клиенте, так и на сервере, и вызывает (некоторый) дополнительный сетевой трафик на эти 2 минуты, чтобы поддерживать связь.

Еще одна интересная вещь: даже если вы вызываете «Создать», это не означает, что при необходимости создается другое соединение TCP. Например, рассмотрим следующее:

static void Doit(string domain) 
{ 
    HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(domain); 

    using (HttpWebResponse response = (HttpWebResponse)hr.GetResponse()) 
     using (Stream receiveStream = response.GetResponseStream()) 
      using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) 
       Console.WriteLine(readStream.ReadToEnd()); 
} 

Теперь, если я называю это с:

Doit("http://www.foo.bar"); 

Это создаст 1 соединение TCP. Он останется активным в течение 2 минут (или до выхода программы). Но что, если я это сделать:

Doit("http://www.foo.bar"); 
Thread.Sleep(20000); 
Doit("http://www.foo.bar"); 

Теперь это создаст 1 соединение для первого вызова, а затем повторное, что соединение для второго вызова. Значение TCP-соединения будет оставаться активным в течение всего 2:20 минут. Поэтому, даже если мы вызываем «Создать», это не создает соединение с нуля.

В основном это хорошая вещь. Создание соединения (особенно HTTPS-соединение) может быть дорогостоящим процессом. Система, которая автоматически избегает этого для вас (вероятно), хорошая вещь. Таким образом, вы можете эффективно извлекать html для веб-страницы, а затем любые связанные файлы поддержки (css, img-файлы и т. Д.) Без необходимости проходить процесс подключения каждый раз.

Но что, если сервер, к которому вы подключаетесь, поддерживает только ограниченное количество соединений? Оставив соединение, связанное таким образом, без уважительной причины, может стать реальной проблемой. Или, возможно, из соображений безопасности вы не можете оставлять связи открытыми надолго? Или, может быть, вы просто анал и хотите закрыть это дело, как только закончите с ним.

Для этих случаев вы можете поэкспериментировать с HttpWebRequest.KeepAlive. Установка этого параметра на false (по умолчанию true) приводит к тому, что каждый из приведенных выше примеров использует свое собственное соединение, закрывая их, как только вы закончите. Таким образом, весь процесс Connect/Send/Receive/Disconnect завершится менее чем за секунду.

FYI:

  • В то время как вы можете использовать WebRequest.InitializeLifetimeService получить ILease, изменив значения на аренду не влияет на время ожидания здесь.
  • Вместо использования WebRequest вы можете использовать WebClient, который поддерживает Dispose. Однако базовое TCP-соединение все еще зависает в течение 2 минут даже после вызова Dispose.

В заключение: Говорить, что вам не нужно беспокоиться о закрытии HttpWebClient, может быть, как правило, правдой, но есть последствия, о которых вы, возможно, захотите узнать. Для этого есть веские причины, но вы не можете решить, хорошо ли это для вашего конкретного приложения, если вы не знаете, что это происходит.

FWIW

Смежные вопросы