HttpClient在使用语句中

时间:2016-10-22 00:30:56

标签: c# httpclient

嗨,我读了这篇文章You're using HttpClient wrong and it is destabilizing your software,文章提出了这两篇

  1. 让你的HttpClient静态
  2. 除非您明确寻找特定行为(例如导致服务失败),否则请勿将HttpClient丢弃或包装在使用中。
  3. 现在像我这样的c#上的新手会跟着它,就像这篇文章上发布的代码是原始代码,他说会使应用程序失败

    using System;
    using System.Net.Http;
    namespace ConsoleApplication
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("Starting connections");
                for(int i = 0; i<10; i++)
                {
                    using(var client = new HttpClient())
                    {
                        var result = client.GetAsync("http://aspnetmonsters.com").Result;
                        Console.WriteLine(result.StatusCode);
                    }
                }
                Console.WriteLine("Connections done");
            }
        }
    }
    

    并修复它,他给出了这段代码:

    using System;
    using System.Net.Http;
    namespace ConsoleApplication
    {
        public class Program
        {
            private static HttpClient Client = new HttpClient();
            public static void Main(string[] args)
            {
                Console.WriteLine("Starting connections");
                for(int i = 0; i<10; i++)
                {
                    var result = Client.GetAsync("http://aspnetmonsters.com").Result;
                    Console.WriteLine(result.StatusCode);
                }
                Console.WriteLine("Connections done");
                Console.ReadLine();
            }
        }
    }
    

    现在好奇,就像任何新手一样,我想到了using语句中的for循环,效果会与后者相同吗?

    谢谢

2 个答案:

答案 0 :(得分:18)

不同之处在于,在顶部循环中,您创建了10个HttpClient对象,每个对象使用一次,然后处理每个对象,而在底部,您只创建一个HttpClient并重复使用它。

文章的重点是,每次要进行Web服务调用时,创建一个新的HttpClient对象效率非常低 - 而且完全没有必要。由于HttpClient不仅可重用而且是线程安全的,因此首选方法是创建一个HttpClient并重复使用它,直到您的程序完成http连接为止。

修改

听起来你问的是为什么不这样:

using System;
using System.Net.Http;
namespace ConsoleApplication
{
    public class Program
    {

        public static void Main(string[] args)
        {
            Console.WriteLine("Starting connections");
            using (var client = new HttpClient())
            {
                for(int i = 0; i<10; i++)
                {
                    var result = Client.GetAsync("http://aspnetmonsters.com").Result;
                    Console.WriteLine(result.StatusCode);
                }
            }
            Console.WriteLine("Connections done");
            Console.ReadLine();
        }
    }
}

在这个特定情况下,没有区别。重要的是HttpClient在每个请求完成之前都会被重用。在大多数现实场景中,为HttpClient提供静态属性最有助于实现此目标。

他们说“不使用”的原因是using暗示您的HttpClient是方法中的局部变量,并且在大多数情况下不是您想要的。在这种特定情况下,来自程序的每个http请求都在一个只调用一次的方法中发生,因此该方法的本地变量很好 - 最终会得到一个HttpClient,它会被重用,直到所有请求都发生,然后是地布置。

答案 1 :(得分:10)

添加答案以引用Microsoft的文档:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

  

HttpClient 旨在实例化一次并在应用程序的整个生命周期中重复使用。特别是在服务器应用程序中,为每个请求创建一个新的 HttpClient 实例将耗尽重负载下可用的套接字数量。这将导致 SocketException 错误。