我们的web应用程序运行在。net Framework 4.0中。UI通过Ajax调用调用控制器方法。
我们需要使用来自供应商的REST服务。我正在评估在。net 4.0中调用REST服务的最佳方式。REST服务需要一个基本的身份验证方案,它可以返回XML和JSON两种格式的数据。
对上传/下载大数据没有任何要求,我认为未来也不会有任何要求。我查看了一些用于REST消费的开源代码项目,并没有发现它们有任何价值来证明项目中的额外依赖。我开始计算WebClient
和HttpClient
。我从NuGet下载了。net 4.0的HttpClient。
我搜索了WebClient
和HttpClient
和这个网站之间的差异,其中提到单个HttpClient可以处理并发调用,并且可以重用已解析的DNS、cookie配置和身份验证。我还没有看到我们可能从这些差异中获得的实际价值。
我做了一个快速的性能测试,以了解WebClient
(同步调用),HttpClient
(同步和异步)的执行情况。结果如下:
我对所有请求使用相同的HttpClient
实例(最小值-最大值)。
WebClient sync: 8 ms - 167 ms
HttpClient sync: 3ms - 7228 ms
HttpClient async: 985 - 10405 ms
为每个请求(最小值-最大值)使用一个新的HttpClient
:
WebClient sync: 4ms - 297 ms
HttpClient sync: 3ms - 7953 ms
HttpClient async: 1027 - 10834 ms
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
会是更好的设计选择吗?性能是关键的设计因素。