我们的web应用程序是:在.NET框架4.0上运行。 该UI通过调用Ajax调用控制器方法。
我们需要从我们的供应商的消费REST服务。 我评估调用REST服务在.NET 4.0中的最佳途径。 REST服务,需要基本身份验证方案,它可以在XML和JSON返回数据。 有上传/下载大量的数据没有要求,我没有看到任何未来。 我接过来一看,在一些开放源码项目REST消费,并没有发现在那些任意值来证明该项目的其他依赖。 开始评估WebClient
和HttpClient
。 我下载的HttpClient对于.NET 4.0的的NuGet。
我搜索之间的差异WebClient
和HttpClient
与本网站提到,单一的HttpClient可以处理并发呼叫,它可以重复使用解析的DNS,饼干配置和认证。 我还没有看到,我们可能会因不同获得的实用价值。
我做了一个快速的性能测试找到如何WebClient
(同步调用), HttpClient
(同步和异步)执行。 和这里的结果:
使用相同HttpClient
实例的所有请求(最小-最大)
Web客户端同步:8毫秒 - 167毫秒
HttpClient的同步:3毫秒 - 7228毫秒
HttpClient的异步:985 - 10405毫秒
使用新HttpClient
为每个请求(最小-最大)
Web客户端同步:4毫秒 - 297毫秒
HttpClient的同步:3毫秒 - 7953毫秒
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);
}
}
}
我的问题
- 其余的调用返回在3-4s这是可以接受的。 调用REST服务在其中被从Ajax调用调用控制器方法启动。 首先,调用在不同的线程上运行,并不会阻止用户界面。 所以,我能带同步调用坚守?
- 上面的代码在我被localbox的运行。 在督促设置,DNS和代理查询将参与其中。 有没有使用任何优势
HttpClient
在WebClient
? - 是
HttpClient
并发性优于WebClient
? 从测试结果来看,我看到WebClient
同步调用有更好的表现。 - 将
HttpClient
是一个更好的设计选择,如果我们升级到.NET 4.5? 性能是关键的设计因素。