决定HttpClient和WebClient
我们的networking应用程序运行在.Net Framework 4.0中。 UI通过ajax调用来调用控制器方法。
我们需要从我们的供应商处使用REST服务。 我正在评估在.NET 4.0中调用REST服务的最佳方式。 REST服务需要基本身份validationscheme,它可以以XML和JSON格式返回数据。 不需要上传/下载庞大的数据,以后我什么都看不到。 我看了一些关于REST消耗的开放源代码项目,并没有在这些项目中find任何价值来说明额外的依赖关系。 开始评估WebClient
和HttpClient
。 我从NuGet下载了.Net 4.0的HttpClient。
我searchWebClient
和HttpClient
之间的差异, 这个网站提到,单个HttpClient可以处理并发调用,它可以重用parsing的DNS,cookieconfiguration和身份validation。 我还没有看到由于差异而可能获得的实际价值。
我做了一个快速的性能testing,以查找WebClient
(同步调用), HttpClient
(同步和asynchronous)如何执行。 这里是结果:
对所有请求使用相同的HttpClient
实例(min – max)
WebClient同步:8毫秒 – 167毫秒
HttpClient同步:3毫秒 – 7228毫秒
HttpClientasynchronous:985 – 10405毫秒
对每个请求使用新的HttpClient
(min – max)
WebClient同步:4毫秒 – 297毫秒
HttpClient同步:3毫秒 – 7953毫秒
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); } } }
我的问题
- REST调用在3-4s内返回,这是可以接受的。 对REST服务的调用是在从Ajax调用中调用的控制器方法中启动的。 首先,调用运行在不同的线程,并不会阻止用户界面。 那么,我可以坚持同步呼叫吗?
- 上面的代码是在我的localbox中运行的。 在prod设置中,将涉及DNS和代理查询。 使用
HttpClient
通过WebClient
有没有什么好处? -
HttpClient
并发性比WebClient
好吗? 从testing结果来看,我发现WebClient
同步调用性能更好。 - 如果我们升级到.Net 4.5,
HttpClient
会是一个更好的deviseselect吗? 性能是关键的devise因素。
我住在F#和Web API世界。
Web API有很多好东西,特别是以安全性的消息处理器的forms。
我知道我只有一个意见,但我只会build议使用HttpClient
的任何未来的工作 。 也许有一些方法来利用一些从System.Net.Http
出来的其他部分,而不是直接使用该程序集,但我无法想象这是如何工作在这个时候。
说到比较这两个
- HttpClient比WebClient更接近HTTP。
- HttpClient并不是完全取代Web客户端,因为有些事情像报告进度,自定义URIscheme和WebClient提供的FTP调用 – 但是HttpClient不支持。
如果您使用.NET 4.5,请使用Microsoft为开发人员提供的HttpClient的asynchronous优势。 HttpClient对于服务器端的兄弟们来说非常对称,那就是HttpRequest和HttpResponse。
更新:使用新的HttpClient API的5个理由:
- 强types的标题。
- 共享caching,Cookie和凭证
- 访问Cookie和共享Cookie
- 控制caching和共享caching。
- 注入你的代码模块到ASP.NETpipe道中。 清洁和模块化的代码。
参考
C#5.0 Joseph Albahari
(Channel9 – Video Build 2013)
使用新的HttpClient API连接到Web服务的五大原因
WebClient与HttpClient与HttpWebRequest
HttpClient是API中较新的,它的好处是
- 有一个很好的asynchronous编程模型
- 正在由Henrik F Nielson工作,他基本上是HTTP的发明者之一,他devise了API,因此您可以轻松遵循HTTP标准,例如生成符合标准的头文件
- 是在.Net框架4.5,所以它有一定的保证水平支持可预见的未来
- 如果你想在其他平台上使用它,你也可以使用该库的xcopyable / portable-framework版本 – .NET 4.0,Windows Phone等
如果您正在编写一个正在对其他Web服务进行REST调用的Web服务,那么您应该对所有REST调用都使用asynchronous编程模型,这样就不会遇到线程匮乏的情况。 你可能也想用最新的C#编译器,它有asynchronous/等待支持。
注意:这不是更高性能的AFAIK。 如果你创build一个公平的testing,可能有点类似的performance。
首先,我不是WebClient与HttpClient的权威,具体来说。 其次,从上面的评论,似乎表明,WebClient是同步,而HttpClient是两个。
我做了一个快速的性能testing,以查找WebClient(同步调用),HttpClient(同步和asynchronous)如何执行。 这里是结果。
我认为这是一个巨大的差异时,考虑未来,即长期运行的过程,响应式graphics用户界面等(增加你的build议由框架4.5的好处 – 在我的实际经验是在IIS上快得多)
- 如何使用.Net Core开发跨平台的gui应用程序
- 远程计算机无法连接到Visual Studio Web服务器
- .NET有图标集合吗?
- 任何方式使DataContractJsonSerializer正确地序列化字典?
- 在.NET中有一个简单的方法来获得数字的“st”,“nd”,“rd”和“th”结尾吗?
- 有没有好的免费.Netnetworking库? (FTP,SFTP,SSH等)
- .NET Core,.NET Framework和Xamarin有什么区别?
- 我可以在Visual Studio 2008中开发.NET Framework 4吗?
- 如果我在Try块中返回一个值,将会在finally语句中编写代码?