2016-04-24 22 views
1

Webリクエストでは、Microsoft HttpClientを使用して別のサーバーを呼び出したいと思っています。私はMVC4(IISでホストされている)を使用しており、castle-windsorをIOCコンテナとして使用しています。私は、HttpClientがサーバーコール中に生きるように設計されていることを読んで、私の質問はこれをどのように実装すべきかということです。MVC4のHttpClientのライフスタイル(Castle-Windsorを使用)

私はいくつかのオプションを思い付く:

  1. はHttpClientをが複数の呼び出しのために設計されており、新しいものに私は1つを必要とするたびに作成されているという事実を無視します。
  2. コール間のHttpClientを格納するシングルトン(城のライフスタイル)オブジェクトを作成します。これにはどんなリスクがありますか?複数のWebリクエストが同じHTTPクライアントを使用している場合、パフォーマンスは悪くなりますか?

これを行うためのパターンはありますか?

答えて

2

私はを使用して、リクエストごとに新しいものを作成します。クラスがシングルトンとして機能することが確実でないときは、最も安全です。

HTTPリクエストを行う以外にクラスが決して使用されないことが確実でない限り、HttpClientではなく抽象(インターフェイス)に直接依存することも悪い考えではありません。それでも単体テストが楽になるかもしれません。それはWindsorや別のDIコンテナを使う大きな利点の1つです。それ以外の場合は、クラス内に直接HttpClientをインスタンス化するだけではあまり効果がありません。


更新。私はいくつか探して、HttpClientが与えられたAPIのために再利用されるべきであることを示すthis answerを見つけました。それは非常に上向きであり、私は経験(またはそうでなければ)からの意見の相違は見られないので、近い将来にいくつかの開発を行う際に参照するつもりです。

これを実装するには、インターフェイスを実装する厳密に型指定されたクライアントクラスを定義し、クラス内のインターフェイス(クライアント上では直接使用できない)に応じて定義します。次にWindsorはインターフェイス用のクラスを作成し、シングルトンとして。

+0

これは、 'HttpClient'が複数の(別のスレッドからの)呼び出しを一度に良好なパフォーマンスで処理できることを意味しますか?呼び出しがロックで行われた場合、performaceは悪くなります。その場合、 'HttpClient'のプールを実装することをお勧めします – jabocop

+0

これは議論の内容です。実際には、そうしないとパフォーマンスの問題が発生する可能性があります。私は大量の経験はまだありません。だから私は注意を払って誤っていると示唆していましたが、私はその性質の作品が出てきているので、何かを探し続けるつもりです。しかし、答え、アップフォート、コメントは良い例です。 –

+0

あなたのコメントをありがとう。私はシングルトンとしてHttpClientを実装します。私はまた、MicrosoftのHttpClientのための[documentation](https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.110%29.aspx)を見つけました。 Net Framwork 4.5と4.6)は、メソッドの束が実際にスレッドセーフであることを示します。 – jabocop

0

デフォルトでは、コールごとにHttpClientの新しいインスタンスを作成すると、各呼び出しで新しいTCP接続が作成され、これにより待ち時間とスループットが低下します。新しいHttpClientインスタンスを作成するには、そのインスタンスに1つの呼び出しデータがある場合は、1つのHttpClientHandlerを持ち、HttpClientCtorに渡します。これにより、HttpClientインスタンス間でTCP接続が共有されます。

スコットは、私たちがこの作業を行った3つのアプローチを示します。私はこれが役立つことを願って、私はstackoverflowに新しいので、明らかに2つ以上のリンクを投稿することはできません。

1)ジャスト/シングルトンWebRequestクラスの静的を持って説明しhere

2)としてHttpRequestMessageと静的/シングルトンのHttpClient、およびパス任意のコールごとのヘッダを持っている| HttpClientHandlerを、そしてdisposeHandlerセットとHttpClient ctorにそれを渡します偽にする。

3)場合によっては、各HttpClient呼び出し後に削除する必要があるDelegatingHandler計測ライブラリがありました。そこで以下のようにDispose()で何もしないWebRequestHandlerを作成し、それをDelegatingHandlerのctorに渡した後、disposeHandlerをfalseに設定してDelegatingHandlerをHttpClientのctorに渡しました。

public class LongLivedWebRequestHandler : WebRequestHandler 
{ 
    public override void Dispose() 
    { 
     // Do nothing... 
    } 
} 
+0

私はどのドキュメントや例を参照できますか?これは私が知る必要があるようなものです。ありがとう –

+0

ええ、ドキュメントは少し薄かったです。 Azureの古典的なWebサービスから別のAzureのWebサービスへの呼び出しがあり、私たちのアウトバウンドとインバウンドの待ち時間の差は〜100msと思っていました。長寿命のWebRequest | HttpClientHandlerを共有すると、ホップごとのペナルティが〜20msに低下しました。 3つの例があります。 – AlejandroOeste

関連する問題