在 HttpClient 和 WebClient 之间做出决定 [英] Deciding between HttpClient and WebClient

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

问题描述

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

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

我们需要使用供应商提供的 REST 服务.我正在评估在 .Net 4.0 中调用 REST 服务的最佳方式.REST 服务需要 Basic Authentication Scheme 并且它可以返回 XML 和 JSON 格式的数据.不需要上传/下载大量数据,将来我也看不到任何东西.我查看了一些用于 REST 消费的开源代码项目,但没有发现任何价值来证明项目中的额外依赖是合理的.开始评估 WebClientHttpClient.我从 NuGet 下载了 .Net 4.0 的 HttpClient.

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.

我搜索了 WebClientHttpClient本站 提到单个 HttpClient 可以处理并发调用,并且可以重用解析的 DNS、cookie 配置和身份验证.我还没有看到我们可能因差异而获得的实用价值.

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.

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

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

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

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

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

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

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

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

WebClient 同步:4 毫秒 - 297 毫秒
HttpClient 同步:3 毫秒 - 7953 毫秒
HttpClient 异步:1027 - 10834 毫秒

WebClient sync: 4 ms - 297 ms
HttpClient sync: 3 ms - 7953 ms
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);
        }
    }
}

我的问题

  1. REST 调用在 3-4 秒内返回,这是可以接受的.调用 REST服务在控制器方法中启动,从阿贾克斯调用.首先,调用在不同的线程中运行,并且不会阻塞 UI.那么,我可以坚持使用同步调用吗?
  2. 上面的代码是在我的 localbox 中运行的.在产品设置中,DNS 和代理将涉及查找.与 WebClient 相比,使用 HttpClient 有什么优势吗?
  3. HttpClient 并发是否比 WebClient 更好?从测试结果来看,我看到 WebClient 同步调用的性能更好.
  4. 如果我们升级到 .Net 4.5,HttpClient 会是一个更好的设计选择吗?性能是关键的设计因素.
  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.

推荐答案

HttpClient 是较新的 API,它具有

HttpClient is the newer of the APIs and it has the benefits of

  • 具有良好的异步编程模型
  • 由 Henrik F Nielson 负责,他基本上是 HTTP 的发明者之一,他设计了 API,因此您可以轻松遵循 HTTP 标准,例如生成符合标准的标头
  • 在 .Net 框架 4.5 中,因此在可预见的未来有一定程度的支持
  • 如果您想在其他平台(.Net 4.0、Windows Phone 等)上使用它,还有该库的 xcopyable/portable-framework 版本.

如果您正在编写一个对其他 Web 服务进行 REST 调用的 Web 服务,您应该希望对所有 REST 调用使用异步编程模型,这样您就不会遇到线程饥饿.您可能还想使用支持 async/await 的最新 C# 编译器.

If you are writing a web service which is making REST calls to other web services, you should want to be using an async programming model for all your REST calls, so that you don't hit thread starvation. You probably also want to use the newest C# compiler which has async/await support.

注意:AFAIK 的性能并不高.如果您创建一个公平的测试,它的性能可能有点相似.

Note: It isn't more performant AFAIK. It's probably somewhat similarly performant if you create a fair test.

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

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