.net - 捨て方 - httpwebrequestを処分する正しい方法はありますか?




小さい鏡 捨て方 (4)

HttpWebRequestはIDisposableを実装していないため、廃棄する必要はありません。 いったん完了したら、httprequestオブジェクトをnullに設定してください。

それが役に立てば幸い

私はHttpWebRequestを使用してHttpWebRequest 、応答ストリームをHttpWebRequestしています。 HttpWebRequestの処理方法としては、closeメソッドやdisposeメソッドが含まれていないため、正しい方法がありますか?


httpwebRequestは、IDisposableを実装するStreamを作成できるため、IDisposableを実装していません。 そのように、あなたはそれを処分する心配はありません。

あなたが心配している場合は、IDisposableであるWebClientを使用することができます:

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

クラスに特別処理要件がある場合、IDisposableが実装されます。 IDisposableを実装していないので、何もする必要はないと思われるかもしれません。


私も同様の質問をしていましたが、ここでの答えは必要な情報を私に与えませんでした。 だから受け入れられた答えがあっても、私は次の男を助けるために学んだことを追加するつもりです。

1)他のいくつかの答えに言及すると、HttpWebRequest / WebRequestから返されたストリームに対してusingを使用できます。 これはちょうどいい標準のC#プログラミングです。

しかし、HttpWebRequestオブジェクト自体を破棄することに関するOPの質問(または私の問題)には実際には言及していません。

2)HttpWebRequestを取得する関数の名前が「Create」であるにもかかわらず、Destroy、Close、Dispose、または作成されたオブジェクトからリソースを解放するために使用できる他のメカニズムはありません。

これは基本的に現在受け入れられている答えです。

3)しかし、ここでの答えの中には、(流れ以外の)重要なものはありません。 それは完全に正しいわけではありません。

ProcMonを使用すると、 GetResponse()を呼び出すときに発生するTCP ConnectTCP Send 、およびTCP ReceiveGetResponse()できます。 これは私が期待するものです。 しかし、いつTCP Disconnectが行われますか? 私の前提は、応答の受信が完了した後、またはオブジェクトがGCされた最悪の場合に発生するということでした。 しかし、現実はもっと面白いです。

代わりに、TCP接続は、呼び出し後2分間正確にアクティブのままです。 私が最初に考えたのは、GCがそれに近づくのにどれくらいの時間がかかるのかということでしたが、そうではありませんでした。 GC.Collect()ループで2分間そこに座ることができます.2分間経過するまで放置しません。 これにより、クライアントとサーバーの両方で接続が開いたままになり、2分間追加のネットワークトラフィックが発生して接続が維持されます。

別の興味深いことは、あなたが 'Create'を呼んでいても、別の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つの接続を作成し、2回目のコールでその接続を再利用します。 つまり、TCP接続は2分20秒間アクティブのままになります。 したがって、「作成」と呼んでいても、接続を最初から作成するわけではありません。

ほとんどこれは良いことです。 接続(特にHTTPS接続)を行うことは、コストのかかるプロセスになります。 それを自動的に回避するシステムは(おそらく)良いことです。 そうすれば、Webページのhtmlを効率的に検索し、関連するサポートファイル(css、imgファイルなど)を毎回検索する必要がなくなります。

しかし、接続先のサーバーが限られた数の接続しかサポートしていない場合はどうなりますか? 正当な理由がないのにこのように結ばれたままにしておくことは本当の問題かもしれません。 あるいは、セキュリティ上の理由から、長い間接続を開いたままにすることはできませんか? あるいは、あなたはただの肛門で、それを済ませたらただちに物事を止めたいと思うかもしれません。

このような場合は、 HttpWebRequest.KeepAliveHttpWebRequest.KeepAliveことができます。 これをfalse (デフォルトはtrue )に設定すると、上記の各例はそれぞれ独自の接続を使用し、完了後すぐにそれらをシャットダウンします。 このように、接続/送信/受信/切断プロセス全体は1秒未満で完了することができます。

参考:

  • WebRequest.InitializeLifetimeServiceを使用してILeaseを取得できますが、リースの値を変更してもここのタイムアウトには影響しません。
  • WebRequestを使用する代わりに、DisposeをサポートするWebClientを使用できます。 しかし、Disposeを呼び出した後でも、基本的なTCP接続は2分間もハングアップします。

結論として、HttpWebClientをシャットダウンすることについて心配する必要はないと言うのは一般的には正しいかもしれませんが、意識したいことがあります。 この動作には十分な理由がありますが、それが起こっていることがわからない場合は、特定のアプリケーションに適しているかどうかを判断できません。

FWIW





httpwebrequest