HttpClientを同時に使用しても安全ですか?


151

私が使用できるすべての例でHttpClient、1回限りの呼び出しに使用されます。しかし、複数の要求を同時に行うことができる永続的なクライアント状況がある場合はどうなりますか?基本的に、client.PostAsyncの同じインスタンスに対して一度に2つのスレッドを呼び出しても安全ですかHttpClient

私は実際にここで実験結果を探しているわけではありません。実際の例としては、単純にまとまりのあるもの(および永続的なもの)である可能性があり、失敗した例の場合は、構成の問題がある可能性があります。理想的には、HttpClientでの並行処理の問題に対する信頼できる回答を探しています。


2
適切に使用HttpClientおよび処分する方法の詳細については、この質問もお読みください。stackoverflow.com/ questions / 15705092
Mani Gandham

回答:


152

MSDNよると、.NET 4.5以降、次のインスタンスメソッドはスレッドセーフです(@ischellに感謝)。

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync

3
うん、それはMSDNのすべてに対する標準的な警告のように見えるので、私はそれについて確信がありませんでした(そして、警告がすべてに盲目的に適用されるため、その警告がどのように間違っているかについていくつかのMSDNブログを読んだことを覚えています)。
Alex K

3
これは間違っています; リンクしたMSDNページの備考セクションで、GetAsync、PostAsyncなどはすべてスレッドセーフであると述べています。
ischell 2013年

4
@ischell:この問題が議論されたときに問題の段落がそこになかったことを保証できます。
Marcel N.

7
したがって、MicrosoftはHttpClientを再利用可能に設計しましたが、そのクラスにはヘッダーのインスタンスデータがあります。client.DefaultRequestHeaders.Accept.Add(...);
cwills 2014年

8
最近、@ cwillsについてコメントしたかった。DefaultRequestHeadersは、デフォルトです。リクエストごとに異なるヘッダーが必要な場合は、新しいStringContent()を作成し、追加のヘッダーを設定してから、URIとHttpContentを受け取るオーバーロードを使用できます。
ライアンアンダーソン

92

Henrik F. NielsenによるHttpClientに関する別の記事は次のとおりです。

" デフォルトのHttpClientは、リクエストの送信を開始する最も簡単な方法です。単一のHttpClientを使用して、必要な数のHTTPリクエストを同時に送信できるため、多くのシナリオでは、1つのHttpClientを作成し、それをすべてのリクエストに使用できます。 。 "


13
ユーザー名とパスワードがスレッド間で変更できる場合はどうなりますか?それは私が話している誰かを見つけることができないようです
Nicholas DiPiazza

1
@NicholasDiPiazza:どのくらいの頻度で変化しますか?ユーザーとパスワードのペアの既知のセットがある場合は、HttpClientインスタンスのプールを作成できます。
Marcel N.

うん

2
すべてのリクエストに対して同じHttpClientを再利用すると、古いDNS問題が発生する可能性があることに注意してください:github.com/dotnet/corefx/issues/11224
Ohad Schneider

1
@OhadSchneiderその問題は.netコアに限定されていると信じている場合。カスタムHttpClientHandlerをHttpClientコンストラクターに挿入し、「ConnectionLeaseTimeout」を設定することで、.net 4の問題を修正できます。ただし、リクエストが100秒間エンドポイントに送信されない場合、接続は自動的に更新されます。保護されたオーバーライドTask <HttpResponseMessage> SendAsync(HttpRequestMessage request、CancellationToken cancelToken){var sp = ServicePointManager.FindServicePoint(request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; }
ティモシーゴンザレス

17

Henrik F. Nielsen(HttpClientの主要な設計者の1人)によるMSDNフォーラム投稿を 1つ見つけました。

簡単な要約:

  • 関連する(または互いに踏みにじらない)リクエストがある場合、同じHttpClientを使用することは非常に理にかなっています。
  • 一般的には、可能な限りHttpClientインスタンスを再利用することをお勧めします。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.