需要帮助的HttpClient的和WebClient的决定 [英] Need help deciding between HttpClient and WebClient

查看:288
本文介绍了需要帮助的HttpClient的和WebClient的决定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的Web应用程序是运行在.Net框架4.0。用户界面通过调用Ajax调用控制器方法。

我们需要从我们的供应商消费REST服务。我正在评估调用REST服务在.NET 4.0中的最佳途径。 REST服务,需要基本身份验证方案,并 可以返回的XML和JSON数据。有上传/下载庞大的数据中没有要求,我看不到未来的任何东西。我看了看几个开源$ C ​​$ C项目REST消费,并没有发现这些任意值来证明该项目的其他依赖。开始评估 Web客户端的HttpClient 。我下载的HttpClient对于.NET 4.0的的NuGet。

我搜索 Web客户端的HttpClient 提到,单个HttpClient的可以处理并发呼叫,它可以重复使用解析的DNS,饼干配置和验证这个网站。我还没有看到,我们可能会由于获得对差异的实用价值。

我做了一个快速的性能测试,以找到如何 Web客户端(同​​步调用),的HttpClient (同​​步和异步)演出。这里是结果:

使用相同的的HttpClient 实例的所有请求(最小 - 最大)

  

Web客户端同步:8毫秒 - 167毫秒
  HttpClient的同步:3毫秒 - 7228毫秒
  HttpClient的异步:985 - 10405毫秒

使用新的的HttpClient 为每个请求(最小 - 最大)

  

Web客户端同步:4毫秒 - 297毫秒
  HttpClient的同步:3毫秒 - 7953毫秒
  HttpClient的异步:1027 - 10834毫秒

code

公共类AHNData {     公众诠释我;     公共字符串str; } 公共类节目 {     公共静态HttpClient的HttpClient的=新的HttpClient();     私人静态只读字符串_url =HTTP://本地主机:9000 / API /价值/;     公共静态无效的主要(字串[] args)     {        #地区的跟踪        Trace.Listeners.Clear();        TextWriterTraceListener会twtl =新TextWriterTraceListener会(            C:\\ \\温度REST_Test.txt);        twtl.Name =TextLogger;        twtl.TraceOutputOptions = TraceOptions.ThreadId | TraceOptions.DateTime;        ConsoleTraceListener CTL =新ConsoleTraceListener(假);        ctl.TraceOutputOptions = TraceOptions.DateTime;        Trace.Listeners.Add(twtl);        Trace.Listeners.Add(CTL);        Trace.AutoFlush = TRUE;        #endregion        INT BATCHSIZE = 1000;        ParallelOptions parallelOptions =新ParallelOptions();        parallelOptions.MaxDegreeOfParallelism = BATCHSIZE;        ServicePointManager.DefaultConnectionLimit = 1000000;        的Parallel.For(0,BATCHSIZE,parallelOptions,            J =>            {                秒表SW1 = Stopwatch.StartNew();                GetDataFromHttpClientAsync<列表< AHNData>>(SW1);            });        的Parallel.For(0,BATCHSIZE,parallelOptions,             J =>             {                 秒表SW1 = Stopwatch.StartNew();                 GetDataFromHttpClientSync<列表< AHNData>>(SW1);             });        的Parallel.For(0,BATCHSIZE,parallelOptions,             J =>             {                 使用(Web客户端的客户端=新的Web客户端())                 {                    秒表SW = Stopwatch.StartNew();                    byte []的ARR = client.DownloadData(_url);                    sw.Stop();                    Trace.WriteLine(Web客户端同步+ sw.ElapsedMilliseconds);                 }            });            Console.Read();         }         公共静态牛逼GetDataFromWebClient< T>()         {             使用(VAR Web客户端=新的Web客户端())             {                 webClient.BaseAddress = _url;                 返回JsonConvert.DeserializeObject< T>(                     webClient.DownloadString(_url));             }         }         公共静态无效GetDataFromHttpClientSync< T>(秒表SW)         {             HttpClient的HttpClient的=新的HttpClient();             VAR响应= httpClient.GetAsync(_url)。结果;             VAR OBJ = JsonConvert.DeserializeObject< T>(                 response.Content.ReadAsStringAsync()结果)。             sw.Stop();             Trace.WriteLine(HttpClient的同步+ sw.ElapsedMilliseconds);         }         公共静态无效GetDataFromHttpClientAsync< T>(秒表SW)         {            HttpClient的HttpClient的=新的HttpClient();            VAR响应= httpClient.GetAsync(_url).ContinueWith(               (一)=> {                  JsonConvert.DeserializeObject< T>(                     a.Result.Content.ReadAsStringAsync()结果)。                  sw.Stop();                  Trace.WriteLine(HttpClient的异步+ sw.ElapsedMilliseconds);               },TaskContinuationOptions.None);         }     } }

我的问题

  1. 的REST调用返回3-4s这是可以接受的。呼叫休息 服务在其中被从调用控制器方法启动 Ajax调用。首先,调用在不同的线程运行, 不会阻止用户界面。所以,我能带同步调用坚守?
  2. 在上面的code是在localbox的我跑。在督促设置,DNS和代理 查找将参与其中。有没有使用任何优势的HttpClient Web客户端
  3. 的HttpClient 并发比 Web客户端更好?从测试结果来看,我看 Web客户端同步调用有更好的表现。
  4. 威尔的HttpClient 是一个更好的设计选择,如果我们升级到.NET 4.5?性能是关键的设计因素。
解决方案

我住在这两个F#和Web API的世界。

有很多的好东西发生在Web API,特别是在安全性消息处理程序等。

的形式

我知道我只有一个意见,但我只推荐使用的HttpClient 为今后的任何工作。也许有一些方法来利用一些其他的作品走出 System.Net.Http 而不直接使用该程序集,但我无法想象如何将工作在这个时候。

说起比较这两个

  • 在HttpClient的比Web客户端更接近于HTTP。
  • 的HttpClient并不意味着完全取代Web客户端的,因为有像报告进展情况,自定义的URI方案,使FTP调用Web客户端提供 - 但HttpClient的不

如果您使用的是.NET 4.5,请不要使用异步善良与HttpClient的,微软提供给开发商。 HttpClient的是非常对称的HTTP那些Htt的prequest和Htt的presponse。

服务器端的弟兄

更新:5理由使用新的HttpClient API

强类型头。 共享缓存,cookie和证书 访问饼干和共享饼干 控制缓存与共享缓存。 注入你code模块插入到ASP.NET管道。清洁和模块化code。

参考

C#5.0约瑟夫阿尔巴哈利

(Channel9的 - 视频生成2013)

五大理由使用新的HttpClient API连接到Web服务

Our web app is running in .Net Framework 4.0. The UI calls controller methods through ajax calls.

We need to consume REST service from our vendor. I am evaluating the best way to call REST service in .Net 4.0. The REST service requires Basic Authentication Scheme and it can return data in both XML and JSON. There is no requirement for uploading/downloading huge data and I don't see anything in future. I took a look at few open source code projects for REST consumption and didn't find any value in those to justify additional dependency in the project. Started to evaluate WebClient and HttpClient. I downloaded HttpClient for .Net 4.0 from NuGet.

I searched for differences between WebClient and HttpClient and this site mentioned that single HttpClient can handle concurrent calls and it can reuse resolved DNS, cookie config and authentication. I am yet to see practical values that we may gain due to the differences.

I did a quick performance test to find how WebClient (sync calls), HttpClient (sync and async) perform. and here are the results:

Using same HttpClient instance for all the requests (min - max)

WebClient sync: 8 ms - 167 ms
HttpClient sync: 3 ms - 7228 ms
HttpClient async: 985 - 10405 ms

Using a new HttpClient for each request (min - max)

WebClient sync: 4 ms - 297 ms
HttpClient sync: 3 ms - 7953 ms
HttpClient async: 1027 - 10834 ms

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);
        }
    }
}

My Questions

  1. The REST calls return in 3-4s which is acceptable. Calls to REST service are initiated in controller methods which gets invoked from ajax calls. To begin with, the calls run in a different thread and doesn't block UI. So, can I just stick with sync calls?
  2. The above code was run in my localbox. In prod setup, DNS and proxy lookup will be involved. Is there any advantage of using HttpClient over WebClient?
  3. Is HttpClient concurrency better than WebClient ? From the test results, I see WebClient sync calls perform better.
  4. Will HttpClient be a better design choice if we upgrade to .Net 4.5? Performance is the key design factor.

解决方案

I live in both the F# and Web API worlds.

There's a lot of good stuff happening with Web API, especially in the form of message handlers for security, etc.

I know mine is only one opinion, but I would only recommend use of HttpClient for any future work. Perhaps there's some way to leverage some of the other pieces coming out of System.Net.Http without using that assembly directly, but I cannot imagine how that would work at this time.

Speak­ing of com­par­ing these two

  • Http­Client is more closer to HTTP than Web­Client.
  • Http­Client was not meant to be a com­plete replace­ment of Web Client, since there are things like report progress, cus­tom URI scheme and mak­ing FTP calls that Web­Client pro­vides — but Http­Client doesn’t.

If you’re using .NET 4.5, please do use the async good­ness with Http­Client that Microsoft pro­vides to the devel­op­ers. Http­Client is very sym­met­ri­cal to the server side brethren of the HTTP those are HttpRe­quest and HttpResponse.

Update: 5 Rea­sons to use new Http­Client API

Strongly typed headers. Shared Caches, cook­ies and credentials Access to cook­ies and shared cookies Con­trol over caching and shared cache. Inject your code mod­ule into the ASP.NET pipeline. Cleaner and mod­u­lar code.

Ref­er­ence

C# 5.0 Joseph Albahari

(Channel9 — Video Build 2013)

Five Great Reasons to Use the New HttpClient API to Connect to Web Services

这篇关于需要帮助的HttpClient的和WebClient的决定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆