.NET HttpClient的缺陷

using (HttpClient client = new HttpClient()){}

每次发起http请求每次new httpClient,它会打开许多套接字,比你实际的需求多许多,这极大地增加了服务器的负载。而且,这些套接字实际上不会被using语句关闭。相反,它们是在应用程序停止使用它们几分钟之后才会关闭。

当你销毁它时,它就启动一个进程,关闭在它控制之下的套接字。也就是说,你下次请求连接时,必须重复整个连接新建过程。如果网络延迟很高,或者连接是受保护的(需要新一轮的SSL/TLS协商),就会非常痛苦。

关闭一个套接字需要花费4分钟,关闭套接字的过程并不快。当“关闭”套接字时,你真正做的是将其状态置为TIME_WAIT。在一个预先配置好的时间窗口内,Windows将保持该套接字的状态不变,默认情况下是4分钟。这是为了防止有任何剩余的数据包仍在传输。


这大大增加了可用套接字耗尽的可能,导致运行时错误,比如“无法连接到远程服务器。System.Net.Sockets.SocketException:每个套接字地址(协议/网络地址/端口)通常只允许使用一次”。

Microsoft P&P建议创建一个HttpClient实例,把它存储在一个静态字段中,并在应用程序的生存期内共享该实例,而不是根据需求创建和销毁。

 

public class GoodController : ApiController
{
    // OK
    private static readonly HttpClient HttpClient;
    static GoodController()
    {
        HttpClient = new HttpClient();
    }
}
You create a single static instance of HttpClient. In console or desktop applications, you can expose this instance just about anywhere. In an ASP.NET Web API application, you can create it in the Global.asax.cs file.

namespace HttpClientGuidance
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        internal static HttpClient httpClientInstance;
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
            Uri baseUri = new Uri("https://someresource.com");
            httpClientInstance = new HttpClient();
            httpClientInstance.BaseAddress = baseUri;
            httpClientInstance.DefaultRequestHeaders.Clear();
            httpClientInstance.DefaultRequestHeaders.ConnectionClose = false;
            httpClientInstance.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            ServicePointManager.FindServicePoint(baseUri).ConnectionLeaseTimeout = 60 * 1000;
        }
    }
}

 

 

欢迎大家关注微信号,搜索一下微信公众号名称:DotNet修炼宝典。 或者扫一扫以下二维码,有惊喜额

 

转载于:https://www.cnblogs.com/MaxInfo/p/8288922.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值