C#: "Использование" операторов с HttpWebRequests/HttpWebResponses

Джон Скит (через Twitter) прокомментировал мой код SOApiDotNet (библиотека.NET для API-интерфейса переполнения стека до альфа-версии):

@ maximz2005 Одна вещь, которую я заметил только после быстрого просмотра источника: вы не избавлялись (так) от WebResponses. "используя" заявления FTW.

Он указывает, что мне нужно обернуть эти веб-сеансы в операторы "using". Тем не менее, у меня есть вопрос по этому поводу: должен ли я обернуть все это, начиная с HttpWebRequest, или я должен создать WebRequest вне оператора "using", а затем обернуть Response внутри? У меня такое ощущение, что разница в том, что в первом случае оба объекта будут утилизированы - это правильно?

Заранее спасибо.

3 ответа

Решение

HttpWebRequest сам по себе не одноразовый в отличие HttpWebResponse, Вы должны обернуть одноразовые ресурсы с помощью, чтобы позволить раннюю и решительную очистку. Правильно реализовано IDisposable шаблон позволяет несколько звонков Dispose без каких-либо проблем, так что даже внешний оператор using оборачивает ресурс, который во время его собственной утилизации располагает внутренним ресурсом using, он все еще в порядке.

Пример кода

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

Все, что заключено в блок using () {} (то есть внутри первых скобок), удаляется при выходе из области видимости.

До сих пор я не использовал вашу библиотеку (хотя это и выглядит неплохо), но я бы сказал, что вы должны явно распоряжаться каждым IDisposable, который вы создаете (= несете ответственность), и не возвращаться к вызывающей стороне.

Обозначение, так как я видел, как многие люди борются с множеством вещей, чтобы избавиться: вместо

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

который требует много вертикального пространства, вы можете написать

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

Чтобы предотвратить утечки памяти, вы должны вызывать Dispose для каждого объекта, который реализует IDisposable. Вы можете убедиться, что метод Dispose вызывается с помощью ключевого слова using (без каламбура), так как это всего лишь синтаксический сахар для блока try-finally.

Другие вопросы по тегам