HttpClient と HttpClientHandler はリクエスト間で破棄する必要がありますか? 質問する

HttpClient と HttpClientHandler はリクエスト間で破棄する必要がありますか? 質問する

システム.Net.Http.HttpClientそしてSystem.Net.Http.HttpClientHandler.NET Framework 4.5ではIDisposableを実装します(System.Net.Http.HttpMessageInvoker)。

声明using文書には次のように記されている。

原則として、IDisposable オブジェクトを使用する場合は、using ステートメントで宣言してインスタンス化する必要があります。

この答えこのパターンを使用します:

var baseAddress = new Uri("http://example.com");
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler) { BaseAddress = baseAddress })
{
    var content = new FormUrlEncodedContent(new[]
    {
        new KeyValuePair<string, string>("foo", "bar"),
        new KeyValuePair<string, string>("baz", "bazinga"),
    });
    cookieContainer.Add(baseAddress, new Cookie("CookieName", "cookie_value"));
    var result = client.PostAsync("/test", content).Result;
    result.EnsureSuccessStatusCode();
}

しかし、Microsoft の最も目立った例では、Dispose()明示的にも暗黙的にも呼び出しが行われていません。たとえば、次のようになります。

の中に発表のコメントについて、誰かがマイクロソフトの従業員に質問しました。

サンプルを確認したところ、HttpClient インスタンスで dispose アクションが実行されていないことがわかりました。アプリでは、using ステートメントを使用して HttpClient のすべてのインスタンスを使用しており、HttpClient は IDisposable インターフェイスを実装しているため、これが正しい方法だと思いました。正しい方向に進んでいるでしょうか?

彼の答えはこうでした。

一般的にはそれは正しいですが、.Net 4 では「using」と async は実際には混在しないので注意が必要です。.Net 4.5 では、「using」ステートメント内で「await」を使用できます。

ちなみに、同じ HttpClient を何度でも再利用できるので、通常は頻繁に作成/破棄する必要はありません。

2 番目の段落はこの質問には不必要です。この質問は、HttpClient インスタンスを何回使用できるかではなく、不要になった後に破棄する必要があるかどうかに関するものです。

(更新: 実際、@DPeden が以下で提供しているように、2 番目の段落が答えの鍵となります。)

私の質問は次のとおりです:

  1. 現在の実装 (.NET Framework 4.5) では、HttpClient および HttpClientHandler インスタンスで Dispose() を呼び出す必要がありますか? 説明: 「必要」とは、破棄しないことでリソース漏洩やデータ破損のリスクなど、悪影響が生じる可能性があることを意味します。

  2. 必要でない場合は、IDisposable を実装しているので、とにかく「良い方法」になるでしょうか?

  3. 必要(または推奨)であれば、このコード上記で述べたように、これを安全に実装できますか (.NET Framework 4.5 の場合)?

  4. これらのクラスで Dispose() を呼び出す必要がない場合、なぜ IDisposable として実装されたのでしょうか?

  5. 要求されている場合、または推奨されている場合、Microsoft の例は誤解を招くもの、または安全でないものですか?

ベストアンサー1

一般的な合意としては、HttpClient を破棄する必要はない (すべきではない) ということです。

その仕組みに深く関わっている多くの人々が、このことを述べています。

見るダレル・ミラーのブログ投稿関連するSOの投稿:HttpClient のクロールによりメモリ リークが発生する参考のため。

また、ぜひ読んでみてくださいASP.NET による進化型 Web API の設計の HttpClient の章内部で何が起こっているか、特にここで引用した「ライフサイクル」セクションのコンテキストについては、以下を参照してください。

HttpClient は間接的に IDisposable インターフェイスを実装していますが、HttpClient の標準的な使用法では、要求のたびにそれを破棄するわけではありません。HttpClient オブジェクトは、アプリケーションが HTTP 要求を行う必要がある限り存続するように設計されています。オブジェクトが複数の要求にわたって存在すると、DefaultRequestHeaders を設定するための場所が有効になり、HttpWebRequest で必要だったように、要求ごとに CredentialCache や CookieContainer などを再指定する必要がなくなります。

あるいは、DotPeek を開いてみることもできます。

おすすめ記事