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

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

问题描述

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



我们需要使用供应商提供的REST服务。我正在评估在.Net 4.0中调用REST服务的最佳方法。 REST服务需要基本身份验证方案,并且
可以返回XML和JSON数据。无需上传/下载大量数据,以后也看不到任何东西。我查看了一些用于REST的开源代码项目,但没有发现任何有价值的项目来证明该项目中的其他依赖性。开始评估 WebClient HttpClient 。我从NuGet下载了.Net 4.0的HttpClient。



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



我进行了快速性能测试,以了解 WebClient (同步调用), HttpClient (同步和异步)执行。结果如下:



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


WebClient同步:8 ms-167 ms

HttpClient同步:3 ms-7228 ms

HttpClient异步:985-10405毫秒


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


WebClient同步:4毫秒-297毫秒

HttpClient同步:3毫秒-7953毫秒< br>
HttpClient异步:1027-10834 ms




代码



< pre class = lang-cs prettyprint-override> 公共类AHNData
{
public int i;
公共字符串str;
}

公共类程序
{
public static HttpClient httpClient = new HttpClient();
私有静态只读字符串_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 =>
{
使用(WebClient client = new WebClient())
{
Stopwatch sw = Stopwatch.StartNew();
byte [] arr = client.DownloadData(_url);
sw.Stop();

Trace.WriteLine( WebClient Sync + sw.ElapsedMilliseconds);
}
});

Console.Read();
}

公共静态T GetDataFromWebClient< T>()
{
使用(var webClient = new WebClient())
{
webClient.BaseAddress = _url;
返回JsonConvert.DeserializeObject< T>(
webClient.DownloadString(_url));
}
}

公共静态无效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-4s的速度返回,这是可以接受的。 REST
    服务的调用在控制器方法中启动,该控制器方法从
    ajax调用中调用。首先,调用在不同的线程中运行,
    不会阻止UI。因此,我可以坚持使用同步调用吗?

  2. 上面的代码在我的本地邮箱中运行。在产品设置中,将涉及DNS和代理
    查找。与 WebClient 相比,使用 HttpClient 有什么优势吗?

  3. HttpClient 的并发性比 WebClient 好吗?从测试结果中,我看到 WebClient 同步调用的性能更好。

  4. HttpClient


解决方案

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



Web API发生了很多好事情,尤其是以安全性消息处理程序的形式出现的。



我知道我只是一个意见,但是我只建议在以后的工作中使用 HttpClient 。也许有某种方法可以利用 System.Net.Http 中的其他部分,而无需直接使用该程序集,但是我无法想象这在现在是如何工作的。



谈到两者的比较




  • HttpClient比WebClient更接近HTTP。

  • HttpClient并不是Web客户端的完整替代品,因为WebClient提供了诸如报告进度,自定义URI方案和进行FTP调用之类的东西,但是HttpClient却没有。 / li>


  + ----------- --------------------------------- + ---------------- ---------------------------- + 
| WebClient | HttpClient |
+ -------------------------------------------- + -------------------------------------------- +
|在旧版本的.NET中可用|仅限.NET 4.5。创建支持|
| |对Web API REST调用的需求不断增长|
+ -------------------------------------------- + -------------------------------------------- +
| WinRT应用程序不能使用WebClient HTTPClient可以与WinRT一起使用
+ -------------------------------------------- + -------------------------------------------- +
|提供下载进度报告|没有下载进度报告|
+ -------------------------------------------- + -------------------------------------------- +
|不重用已解析的DNS,可以重用已解析的DNS,cookie |
|配置的cookie |配置和其他身份验证|
+ -------------------------------------------- + -------------------------------------------- +
|您需要新建一个WebClient来|单个HttpClient可以使并发|
|发出并发请求。 |要求|
+ -------------------------------------------- + -------------------------------------------- +
| WebRequest和|上的薄层HttpWebRequest的薄层和|
| WebResponse | HttpWebResponse |
+ -------------------------------------------- + -------------------------------------------- +
|模拟和测试WebClient很困难模拟和测试HttpClient很容易|
+ -------------------------------------------- + -------------------------------------------- +
|支持FTP |不支持FTP |
+ -------------------------------------------- + -------------------------------------------- +
|同步和异步方法|中的所有IO绑定方法
|可用于IO绑定请求| HTTPClient是异步的|
+ -------------------------------------------- + -------------------------------------------- +

如果您使用的是.NET 4.5,请使用Microsoft提供给开发人员的HttpClient异步特性。 HttpClient与HTTP的服务器端兄弟非常对称,即HttpRequest和HttpResponse。



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




  • 强类型标题。

  • 共享缓存,cookie和凭据

  • 访问c​​ookie和共享cookie

  • 控制缓存和共享缓存。

  • 将代码模块注入ASP.NET管道。更加干净和模块化的代码。



参考



C#5.0 Joseph Albahari



(Channel9-Video Build 2013)



使用新的HttpClient API连接到Web服务的五个重要理由



WebClient vs HttpClient vs HttpWebRequest


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.

+--------------------------------------------+--------------------------------------------+
|               WebClient                    |               HttpClient                   |
+--------------------------------------------+--------------------------------------------+
| Available in older versions of .NET        | .NET 4.5 only.  Created to support the     |
|                                            | growing need of the Web API REST calls     |
+--------------------------------------------+--------------------------------------------+
| WinRT applications cannot use WebClient    | HTTPClient can be used with WinRT          |
+--------------------------------------------+--------------------------------------------+
| Provides progress reporting for downloads  | No progress reporting for downloads        |
+--------------------------------------------+--------------------------------------------+
| Does not reuse resolved DNS,               | Can reuse resolved DNS, cookie             |
| configured cookies                         | configuration and other authentication     |
+--------------------------------------------+--------------------------------------------+
| You need to new up a WebClient to          | Single HttpClient can make concurrent      |
| make concurrent requests.                  | requests                                   |
+--------------------------------------------+--------------------------------------------+
| Thin layer over WebRequest and             | Thin layer of HttpWebRequest and           |
| WebResponse                                | HttpWebResponse                            |
+--------------------------------------------+--------------------------------------------+
| Mocking and testing WebClient is difficult | Mocking and testing HttpClient is easy     |
+--------------------------------------------+--------------------------------------------+
| Supports FTP                               | No support for FTP                         |
+--------------------------------------------+--------------------------------------------+
| Both Synchronous and Asynchronous methods  | All IO bound methods in                    |
| are available for IO bound requests        | HTTPClient are asynchronous                |
+--------------------------------------------+--------------------------------------------+

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

WebClient vs HttpClient vs HttpWebRequest

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

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