Closed 。这个问题需要多问focused /help/closed-questions 。目前不接受答案。
我们的 Web 应用程序在 .NET Framework 4.0 中运行。 UI 通过 Ajax 调用来调用控制器方法。
我们需要使用供应商提供的 REST 服务。我正在评估在 .NET 4.0 中调用 REST 服务的最佳方式。 REST 服务需要基本的身份验证方案,并且可以返回 XML 和 JSON 格式的数据。
没有任何上传/下载大量数据的要求,而且我未来也看不到任何东西。我查看了一些用于 REST 使用的开源代码项目,但没有发现其中有任何价值可以证明项目中的额外依赖项是合理的。我开始评价WebClient
and HttpClient
。我从下载了 .NET 4.0 的 HttpClientNuGet https://en.wikipedia.org/wiki/NuGet .
我寻找之间的差异WebClient
and HttpClient
and 这个网站 https://web.archive.org/web/20140217233914/http://blogs.k10world.com/technology/webclient-httpclient-consume-http-requests/ 提到单个 HttpClient 可以处理并发调用,并且可以重用已解析的 DNS、cookie 配置和身份验证。我还没有看到我们可能因差异而获得的实际价值。
我做了一个快速的性能测试来找出如何WebClient
(同步调用),HttpClient
(同步和异步)执行。结果如下:
我正在使用相同的HttpClient
所有请求的实例(最小 - 最大)。
WebClient 同步:8 毫秒 - 167 毫秒 HttpClient 同步:3 毫秒 - 7228 毫秒 HttpClient 异步:985 - 10405 毫秒
使用新的HttpClient
对于每个请求(最小值 - 最大值):
WebClient 同步:4 毫秒 - 297 毫秒 HttpClient 同步:3 毫秒 - 7953 毫秒 HttpClient 异步:1027 - 10834 毫秒
Code
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);
}
}
}
我的问题
REST 调用将在 3-4 秒内返回,这是可以接受的。调用 REST
服务在控制器方法中启动,该方法被调用
阿贾克斯呼叫。首先,调用在不同的线程中运行,并且不会阻塞 UI。那么,我可以坚持使用同步调用吗?
上面的代码是在我的本地盒子中运行的。在生产设置中,DNS 和代理
会涉及到查找。使用有什么好处吗HttpClient
over WebClient
?
Is HttpClient
并发性优于WebClient
?从测试结果来看WebClient
同步调用性能更好。
Will HttpClient
如果我们升级到 .NET 4.5,会是更好的设计选择吗?性能是关键的设计因素。