当社のWebアプリは.Net Framework 4.0で動作しています。 UIはajax呼び出しを通してコントローラーメソッドを呼び出します。
ベンダーのRESTサービスを利用する必要があります。私は.NET 4.0でREST serviceを呼び出すための最良の方法を評価しています。 RESTサービスには基本認証方式が必要であり、XMLとJSONの両方でデータを返すことができます。巨大なデータをアップロード/ダウンロードする必要はありません。将来的には何も表示されません。私はREST消費のためのいくつかのオープンソースコードプロジェクトを調べましたが、プロジェクトに追加の依存関係を正当化するためにそれらの中に値を見つけることができませんでした。 WebClient
およびHttpClient
の評価を開始しました。 NuGetからHttpClient for .Net 4.0をダウンロードしました。
私はWebClient
とHttpClient
との違いを探し、 このサイト 一つのHttpClientが同時呼び出しを扱え、解決されたDNS、cookie設定、そして認証を再利用できると述べました。違いによって私たちが得るかもしれない実用的な価値をまだ見ていません。
WebClient
(同期呼び出し)、HttpClient
(同期と非同期)のパフォーマンスを調べるために、簡単なパフォーマンステストを行いました。これが結果です。
すべての要求に同じHttpClient
インスタンスを使用する(最小 - 最大)
Webクライアント同期:8 ms - 167 ms
HttpClient同期:3ミリ秒 - 7228ミリ秒
HttpClient非同期:985 - 10405 ms
リクエストごとに新しいHttpClient
を使用する(最小 - 最大)
Webクライアント同期:4 ms - 297 ms
HttpClient同期:3 ms - 7953 ms
HttpClient非同期:1027 - 10834ミリ秒
public class AHNData
{
public int i;
public string str;
}
public class Program
{
public static HttpClient httpClient = new HttpClient();
private static readonly string _url = "http://localhost:9000/api/values/";
public static void Main(string[] args)
{
#region "Trace"
Trace.Listeners.Clear();
TextWriterTraceListener twtl = new TextWriterTraceListener(
"C:\\Temp\\REST_Test.txt");
twtl.Name = "TextLogger";
twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;
ConsoleTraceListener ctl = new ConsoleTraceListener(false);
ctl.TraceOutputOptions = TraceOptions.DateTime;
Trace.Listeners.Add(twtl);
Trace.Listeners.Add(ctl);
Trace.AutoFlush = true;
#endregion
int batchSize = 1000;
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = batchSize;
ServicePointManager.DefaultConnectionLimit = 1000000;
Parallel.For(0, batchSize, parallelOptions,
j =>
{
Stopwatch sw1 = Stopwatch.StartNew();
GetDataFromHttpClientAsync<List<AHNData>>(sw1);
});
Parallel.For(0, batchSize, parallelOptions,
j =>
{
Stopwatch sw1 = Stopwatch.StartNew();
GetDataFromHttpClientSync<List<AHNData>>(sw1);
});
Parallel.For(0, batchSize, parallelOptions,
j =>
{
using (WebClient client = new WebClient())
{
Stopwatch sw = Stopwatch.StartNew();
byte[] arr = client.DownloadData(_url);
sw.Stop();
Trace.WriteLine("WebClient Sync " + sw.ElapsedMilliseconds);
}
});
Console.Read();
}
public static T GetDataFromWebClient<T>()
{
using (var webClient = new WebClient())
{
webClient.BaseAddress = _url;
return JsonConvert.DeserializeObject<T>(
webClient.DownloadString(_url));
}
}
public static void GetDataFromHttpClientSync<T>(Stopwatch sw)
{
HttpClient httpClient = new HttpClient();
var response = httpClient.GetAsync(_url).Result;
var obj = JsonConvert.DeserializeObject<T>(
response.Content.ReadAsStringAsync().Result);
sw.Stop();
Trace.WriteLine("HttpClient Sync " + sw.ElapsedMilliseconds);
}
public static void GetDataFromHttpClientAsync<T>(Stopwatch sw)
{
HttpClient httpClient = new HttpClient();
var response = httpClient.GetAsync(_url).ContinueWith(
(a) => {
JsonConvert.DeserializeObject<T>(
a.Result.Content.ReadAsStringAsync().Result);
sw.Stop();
Trace.WriteLine("HttpClient Async " + sw.ElapsedMilliseconds);
}, TaskContinuationOptions.None);
}
}
}
HttpClient
よりWebClient
を使用する利点はありますか?HttpClient
の同時実行性はWebClient
よりも優れていますか?テスト結果から、WebClient
同期呼び出しのパフォーマンスが向上していることがわかります。HttpClient
はより良い設計上の選択になりますか?性能が重要な設計要素です。私はF#とWeb APIの両方の世界に住んでいます。
Web APIに関しては、特にセキュリティなどのためのメッセージハンドラの形で、たくさんの良いことが起こっています。
私の意見は1つの意見にすぎませんが、将来の作業にはHttpClient
の使用をお勧めします。そのアセンブリを直接使わずにSystem.Net.Http
から出てくる他の部分を利用する方法があるかもしれませんが、現時点でそれがどのように機能するかは想像できません。
この二つを比較すると言えば
+--------------------------------------------+--------------------------------------------+
| WebClient | HttpClient |
+--------------------------------------------+--------------------------------------------+
| Available in older versions of .NET | .NET 4.5 only. Created to support the |
| | growing need of the Web API REST calls |
+--------------------------------------------+--------------------------------------------+
| WinRT applications cannot use WebClient | HTTPClient can be used with WinRT |
+--------------------------------------------+--------------------------------------------+
| Provides progress reporting for downloads | No progress reporting for downloads |
+--------------------------------------------+--------------------------------------------+
| Does not reuse resolved DNS, | Can reuse resolved DNS, cookie |
| configured cookies | configuration and other authentication |
+--------------------------------------------+--------------------------------------------+
| You need to new up a WebClient to | Single HttpClient can make concurrent |
| make concurrent requests. | requests |
+--------------------------------------------+--------------------------------------------+
| Thin layer over WebRequest and | Thin layer of HttpWebRequest and |
| WebResponse | HttpWebResponse |
+--------------------------------------------+--------------------------------------------+
| Mocking and testing WebClient is difficult | Mocking and testing HttpClient is easy |
+--------------------------------------------+--------------------------------------------+
| Supports FTP | No support for FTP |
+--------------------------------------------+--------------------------------------------+
| Both Synchronous and Asynchronous methods | All IO bound methods in |
| are available for IO bound requests | HTTPClient are asynchronous |
+--------------------------------------------+--------------------------------------------+
.NET 4.5を使用している場合は、Microsoftが開発者に提供しているHttpClientの非同期機能を使用してください。 HttpClientは、HTTPのサーバー側の兄弟HttpRequestとHttpResponseとは非常に対称的です。
更新日:新しいHttpClient APIを使用する5つの理由:
参考文献
C#5.0ジョセフ・アルバハリ
(Channel 9 - Video Build 2013)
HttpClientは新しいAPIであり、以下の利点があります。
他のWebサービスへのREST呼び出しを行うWebサービスを作成している場合は、すべてのREST呼び出しに非同期プログラミングモデルを使用することをお勧めします。スレッドの枯渇を打つ。また、非同期/待機サポートを備えた最新のC#コンパイラを使用することをお勧めします。
注:それはよりパフォーマンスの高いAFAIKではありません。あなたが公正なテストを作成するならば、それはおそらくいくぶん似たような性能を発揮します。
第一に、私はWebClientとHttpClientの関係についての権限ではありません。第二に、上のあなたのコメントから、それはHttpClientが両方であるのに対し、WebClientは同期のみであることを示唆しているようです。
WebClient(同期呼び出し)、HttpClient(同期および非同期)のパフォーマンスを調べるために、簡単なパフォーマンステストを行いました。これが結果です。
私は将来を考えているとき、すなわち長期実行プロセス、レスポンシブGUIなどと考えると大きな違いがあると思います。