HttpClient在使用语句中

ang*_*ogo 19 c# httpclient

嗨,我读到这篇文章你正在使用HttpClient错误,它正在破坏你的软件,文章建议这些2

  1. 使您的HttpClient静态
  2. 除非您明确要查找特定行为(例如导致服务失败),否则不要将HttpClient丢弃或包装在使用中

现在像我这样的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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢

PMV*_*PMV 21

不同之处在于,在顶部循环中,您将创建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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 每次创建一个时,它也会消耗有限的套接字资源。见 http://codereview.stackexchange.com/questions/69950/single-instance-of-reusable-httpclient (3认同)

Jas*_*sen 11

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

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

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