在HttpClient和WebClient之间做出决定

 AMY_Only 发布于 2023-02-11 13:38

我们的网络应用程序在.Net Framework 4.0中运行.UI通过ajax调用调用控制器方法.

我们需要从供应商处使用REST服务.我正在评估在.Net 4.0中调用REST服务的最佳方法.REST服务需要基本身份验证方案,它可以返回XML和JSON中的数据.没有要求上传/下载大量数据,我将来也看不到任何东西.我看了几个用于REST消费的开源代码项目,并没有找到任何值来证明项目中的额外依赖性.开始评估WebClientHttpClient.我从NuGet下载了用于.Net 4.0的HttpClient.

我搜索了WebClient和之间的差异,HttpClient并且该网站提到单个HttpClient可以处理并发调用,它可以重用已解析的DNS,cookie配置和身份验证.我还没有看到由于差异我们可能获得的实用价值.

我做了一个快速的性能测试,以找到WebClient(同步调用),HttpClient(同步和异步)如何执行.以下是结果:

HttpClient对所有请求使用相同的实例(min - max)

WebClient同步:8毫秒 - 167毫秒
HttpClient同步:3毫秒 - 7228毫秒
HttpClient异步:985 - 10405毫秒

HttpClient为每个请求使用new (min - max)

WebClient同步: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>(sw1);
           });
       Parallel.For(0, batchSize, parallelOptions,
            j =>
            {
                Stopwatch sw1 = Stopwatch.StartNew();
                GetDataFromHttpClientSync>(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()
        {
            using (var webClient = new WebClient())
            {
                webClient.BaseAddress = _url;
                return JsonConvert.DeserializeObject(
                    webClient.DownloadString(_url));
            }
        }

        public static void GetDataFromHttpClientSync(Stopwatch sw)
        {
            HttpClient httpClient = new HttpClient();
            var response = httpClient.GetAsync(_url).Result;
            var obj = JsonConvert.DeserializeObject(
                response.Content.ReadAsStringAsync().Result);
            sw.Stop();

            Trace.WriteLine("HttpClient Sync " + sw.ElapsedMilliseconds);
        }

        public static void GetDataFromHttpClientAsync(Stopwatch sw)
        {
           HttpClient httpClient = new HttpClient();
           var response = httpClient.GetAsync(_url).ContinueWith(
              (a) => {
                 JsonConvert.DeserializeObject(
                    a.Result.Content.ReadAsStringAsync().Result);
                 sw.Stop();
                 Trace.WriteLine("HttpClient Async " + sw.ElapsedMilliseconds);
              }, TaskContinuationOptions.None);
        }
    }
}

我的问题

    REST调用以3-4s返回,这是可以接受的.调用REST服务是在从ajax调用调用的控制器方法中启动的.首先,调用在不同的线程中运行,不会阻止UI.那么,我可以坚持同步电话吗?

    上面的代码在我的localbox中运行.在prod设置中,将涉及DNS和代理查找.使用HttpClient结束有什么好处WebClient吗?

    HttpClient并发好过WebClient?从测试结果中,我看到 WebClient同步调用表现更好.

    HttpClient如果我们升级到.Net 4.5,将是一个更好的设计选择吗?性能是关键的设计因素.

Anant Dabhi.. 221

我生活在F#和Web API世界中.

Web API发生了很多好事,特别是以安全性的消息处理程序等形式.

我知道我的意见只有一个,但我只建议HttpClient将来用于任何工作.也许有一些方法可以利用其他部分System.Net.Http而不直接使用该程序集,但我无法想象这将如何起作用.

说到比较这两个

HttpClient比WebClient更接近HTTP.

HttpClient并不是Web客户端的完全替代品,因为有些报告进度,自定义URI方案以及WebClient提供的FTP调用 - 但是HttpClient没有.

在此输入图像描述

如果您使用的是.NET 4.5,请使用Microsoft为开发人员提供的HttpClient的async优度.HttpClient与HTTP的服务器端兄弟非常对称,即HttpRequest和HttpResponse.

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

强类型标题.

共享缓存,cookie和凭据

访问cookie和共享cookie

控制缓存和共享缓存.

将代码模块注入ASP.NET管道.更清晰和模块化的代码.

参考

C#5.0 Joseph Albahari

(Channel9 - Video Build 2013)

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

WebClient vs HttpClient vs HttpWebRequest

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有