「C Sharpとネットワーク - HttpClient」の版間の差分
細 (文字列「</source>」を「</syntaxhighlight>」に置換) |
編集の要約なし |
||
1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
<code>HttpClient</code>クラスは、HTTPリクエストを投げる場合に使用するクラスである。<br> | |||
.NET Framework 4. | <br> | ||
.NET Framework 4.0以前では、それまでは<code>HttpWebRequest</code>クラス、<code>WebClient</code>が使用されていた。<br> | |||
<code>HttpClient</code>クラスは.NET Framework 4.5以降から提供された機能であり、簡単にHTTPリクエストを投げることができるクラスとして追加された。<br> | |||
<br><br> | |||
== HttpClientクラスの仕様 == | |||
<code>HttpClient</code>クラスのインスタンスを生成する時、内部では新しいソケットを開く。<br> | |||
したがって、メソッド内で<code>HttpClient</code>クラスのインスタンスを生成する場合、常に新しいソケットを開くため、リソースを消費することになる。<br> | |||
<br> | |||
<code>HttpClient</code>クラスのインスタンスを破棄した場合、ソケットが閉じるタイミングは、状態が<code>TIME_WAIT</code>に遷移して、暫く時間が経つと自動的に解放される。<br> | |||
<br> | |||
これは、リクエストする頻度が少ない場合は問題無いが、大量にリクエストを行う場合は大きなボトルネックとなる。<br> | |||
<br><br> | |||
== | == アンチパターン == | ||
==== HttpClientクラス ==== | |||
<code>HttpClient</code>クラスのインスタンスの生成において、<code>IDisposable</code>インターフェースを実装しているので<code>using</code>ブロックで囲うものがある。<br> | |||
<br> | |||
しかし、これは通信を実行するごとにソケットを開くことにより、大量のリソースを消費してリソースが枯渇する場合がある。<br> | |||
<syntaxhighlight lang="c#"> | |||
using (var client = new HttpClient()) | |||
{ | |||
await client.PostAsync("http://iketeru-service.com/"); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== HttpRequestMessageクラス ==== | |||
固定のリクエストヘッダや認証情報を付加した<code>HttpRequestMessage</code>クラスを使用する場合、共通の内部メソッドである<code>CreateRequest()</code>を使用する。<br> | |||
これは、<code>HttpRequestMessage</code>クラスのインスタンスを生成した後、<code>SendAsync()</code>メソッドを使用してメッセージを送信する。<br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
var getReult = await client.GetAsync("http://kirakira-service.com/"); | |||
var postRsult = await client.PostAsync("http://sugoi-service.com/"); | |||
</syntaxhighlight> | |||
<br><br> | |||
== 解決策 == | == 解決策 == | ||
<code>HttpClient</code>クラスは、<code>private</code>キーワードおよび<code>static</code>キーワードを指定したプロパティとして持つ必要がある。<br> | |||
<br> | |||
Microsoftの公式ドキュメント[https://docs.microsoft.com/ja-jp/azure/architecture/antipatterns/improper-instantiation/ 不適切なインスタンス化のアンチパターン]の中でこの問題について取り上げており、<br> | Microsoftの公式ドキュメント[https://docs.microsoft.com/ja-jp/azure/architecture/antipatterns/improper-instantiation/ 不適切なインスタンス化のアンチパターン]の中でこの問題について取り上げており、<br> | ||
HttpClientを使用した実装をする時は、インスタンスを静的変数(static)にして使用するとの記載がある。<br> | HttpClientを使用した実装をする時は、インスタンスを静的変数(static)にして使用するとの記載がある。<br> | ||
<br><br> | |||
== サンプルコード == | == サンプルコード == | ||
<syntaxhighlight lang=" | まず、<code>HttpClient</code>クラスのオブジェクトを生成する。<br> | ||
この時、タイムアウトの設定等はコンストラクタで行う必要がある。<br> | |||
<br> | |||
複数の<code>HttoClient</code>クラスを使用して同時に実行する場合も、<code>HttpClient</code>はそのような使用を想定した設計となっている。<br> | |||
<br> | |||
<syntaxhighlight lang="c#"> | |||
class SmapleClass | class SmapleClass | ||
{ | { | ||
34行目: | 68行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
また、1つの<code>HttpClient</code>クラスは1つのソケット(1つのホスト)として使用した方がよいため、<br> | |||
異なるホストにもリクエストを投げる場合は、別の<code>HttpClient</code>クラスのオブジェクトを生成する方がよい。<br> | |||
<br><br> | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:C_Sharp]] | [[カテゴリ:C_Sharp]] |
2024年1月23日 (火) 08:24時点における版
概要
HttpClient
クラスは、HTTPリクエストを投げる場合に使用するクラスである。
.NET Framework 4.0以前では、それまではHttpWebRequest
クラス、WebClient
が使用されていた。
HttpClient
クラスは.NET Framework 4.5以降から提供された機能であり、簡単にHTTPリクエストを投げることができるクラスとして追加された。
HttpClientクラスの仕様
HttpClient
クラスのインスタンスを生成する時、内部では新しいソケットを開く。
したがって、メソッド内でHttpClient
クラスのインスタンスを生成する場合、常に新しいソケットを開くため、リソースを消費することになる。
HttpClient
クラスのインスタンスを破棄した場合、ソケットが閉じるタイミングは、状態がTIME_WAIT
に遷移して、暫く時間が経つと自動的に解放される。
これは、リクエストする頻度が少ない場合は問題無いが、大量にリクエストを行う場合は大きなボトルネックとなる。
アンチパターン
HttpClientクラス
HttpClient
クラスのインスタンスの生成において、IDisposable
インターフェースを実装しているのでusing
ブロックで囲うものがある。
しかし、これは通信を実行するごとにソケットを開くことにより、大量のリソースを消費してリソースが枯渇する場合がある。
using (var client = new HttpClient())
{
await client.PostAsync("http://iketeru-service.com/");
}
HttpRequestMessageクラス
固定のリクエストヘッダや認証情報を付加したHttpRequestMessage
クラスを使用する場合、共通の内部メソッドであるCreateRequest()
を使用する。
これは、HttpRequestMessage
クラスのインスタンスを生成した後、SendAsync()
メソッドを使用してメッセージを送信する。
var getReult = await client.GetAsync("http://kirakira-service.com/");
var postRsult = await client.PostAsync("http://sugoi-service.com/");
解決策
HttpClient
クラスは、private
キーワードおよびstatic
キーワードを指定したプロパティとして持つ必要がある。
Microsoftの公式ドキュメント不適切なインスタンス化のアンチパターンの中でこの問題について取り上げており、
HttpClientを使用した実装をする時は、インスタンスを静的変数(static)にして使用するとの記載がある。
サンプルコード
まず、HttpClient
クラスのオブジェクトを生成する。
この時、タイムアウトの設定等はコンストラクタで行う必要がある。
複数のHttoClient
クラスを使用して同時に実行する場合も、HttpClient
はそのような使用を想定した設計となっている。
class SmapleClass
{
private static readonly HttpClient httpclient = null;
static SampleClass()
{
httpclient = new HttpClient();
}
public async Task<SomeResponse> CallAPI()
{
await httpclient.PostAsync("{URL}");
...
}
}
また、1つのHttpClient
クラスは1つのソケット(1つのホスト)として使用した方がよいため、
異なるホストにもリクエストを投げる場合は、別のHttpClient
クラスのオブジェクトを生成する方がよい。