HttpClient的之间和WebClient的决定HttpClient的之间和WebClient的

2019-05-08 22:30发布

我们的web应用程序是:在.NET框架4.0上运行。 该UI通过调用Ajax调用控制器方法。

我们需要从我们的供应商的消费REST服务。 我评估调用REST服务在.NET 4.0中的最佳途径。 REST服务,需要基本身份验证方案,它可以在XML和JSON返回数据。 有上传/下载大量的数据没有要求,我没有看到任何未来。 我接过来一看,在一些开放源码项目REST消费,并没有发现在那些任意值来证明该项目的其他依赖。 开始评估WebClientHttpClient 。 我下载的HttpClient对于.NET 4.0的的NuGet。

我搜索之间的差异WebClientHttpClient与本网站提到,单一的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);
        }
    }
}

我的问题

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

Answer 1:

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

有很多的好东西使用Web API发生的事情,特别是在安全性等消息处理程序的形式

我知道我只有一个意见,但我只想建议使用HttpClient任何未来的工作 。 也许有一些方法来利用一些其他的作品出来的System.Net.Http不直接使用该程序集,但我怎么也想不到会在这个时候工作。

比较这两个发言

  • HttpClient的比Web客户端更接近HTTP。
  • HttpClient的不意味着是一个完整的更换Web客户端的,因为有一些事情,如报表的进步,自定义URI方案,使FTP调用Web客户端提供 - 但HttpClient的不。

如果您使用.NET 4.5,请不要使用带有HttpClient的异步善良,微软提供给开发者。 HttpClient的是非常对称于HTTP那些的HttpRequest和HttpResponse对象的服务器侧兄弟。

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

  • 强类型头。
  • 共享缓存,cookie和证书
  • 访问饼干和曲奇共享
  • 控制缓存和共享高速缓存。
  • 注入你的代码模块进入ASP.NET管道。 清洁和模块化的代码。

参考

C#5.0约瑟夫阿尔巴哈利

(Channel9的 - 视频制作2013)

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

Web客户端VS的HttpClient VS的HttpWebRequest



Answer 2:

HttpClient的是这些API的更新,它的好处

  • 具有良好的异步编程模型
  • 正在处理亨里克·尼尔森˚F谁基本上是HTTP的发明者之一,他设计的API,所以很容易让你遵循HTTP标准,例如,创造符合标准的头
  • 是在.NET Framework 4.5,所以它有支持可预见的未来的一些保障水平
  • 也有图书馆的xcopyable /便携式框架版本,如果你想用它在其他平台上 - .NET 4.0的Windows Phone等。

如果你正在写这正在REST Web服务调用其它Web服务,你应该要使用异步编程模型为所有REST调用,让你不打线程匮乏。 您可能还需要使用具有异步/等待支持最新的C#编译器。

注:这是不是更好的性能AFAIK。 如果你创造一个公平的测试这可能有点类似于高性能。



Answer 3:

首先,我不是Web客户端与HttpClient的一个权威,明确。 其次,从上面您的意见,这似乎表明,Web客户端是只同步而HttpClient的是两者兼而有之。

我做了一个快速的性能测试找到如何WebClient的(同步调用),HttpClient的(同步和异步)执行。 和这里的结果。

我认为这是思考未来的时候,也就是长时间运行的进程的巨大差异,响应GUI等(由框架4.5添加到您建议的益处 - 这在我的实际经验是巨大快于IIS)



文章来源: Deciding between HttpClient and WebClient