web-dev-qa-db-ja.com

C#:HttpWebRequests / HttpWebResponsesでのステートメントの「使用」

Jon Skeet (Twitter経由で)コメントをしました 私の SOApiDotNet コード(プレアルファ版Stack Overflow APIの.NETライブラリ):

@ maximz2005ソースをすばやく閲覧しただけで気付いたのは、WebResponseを(原文のまま)破棄していないということです。 「using」ステートメントFTW。

彼は、これらのWebセッションを「using」ステートメントでラップする必要があることを示しています。ただし、これについて質問があります。HttpWebRequestで始まるすべてをラップするまたは、「using」ステートメントの外部でWebRequestを作成してから、Responseをラップする必要があります。内部?前者の場合、両方のオブジェクトが破棄されるという違いがあると感じています-これは正しいですか?

前もって感謝します。

21
Maxim Zaslavsky

HttpWebRequest自体は、HttpWebResponseとは異なり使い捨てではありません。使い捨てのリソースをを使用してラップし、早期かつ確実なクリーンアップを可能にする必要があります。正しく実装されたIDisposableパターンでは、問題なくDisposeを複数回呼び出すことができるため、外部のusingステートメントでもリソースをラップし、それ自体の破棄中に内部のusingステートメントリソースを破棄しても問題ありません。

コード例

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

Using(){}ブロックでラップされたもの(つまり、最初の角かっこ内)はすべて、スコープを離れると破棄されます。

私はこれまであなたのライブラリを使用していませんが(Niceのようです)、作成したすべてのIDisposableを明示的に破棄し(=責任があります)、呼び出し元に戻らないようにする必要があると主張します。

補足、私は多くの人々が処分するために複数のものに苦労しているのを見たので:代わりに

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

あなたが書くことができる多くの垂直スペースを必要とする

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

メモリリークを防ぐために、IDisposableを実装するすべてのオブジェクトでDisposeを呼び出す必要があります。 disposeメソッドは、try-finallyブロックの単なる構文糖衣であるため、usingキーワード(しゃれは意図されていません)を使用して呼び出されるようにすることができます。

1
Giorgi