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修炼宝典。 或者扫一扫以下二维码,有惊喜额

.NET HttpClient的缺陷的更多相关文章

  1. ASP.Net Core2.1中的HttpClientFactory系列一:HttpClient的缺陷

    引言: ASP.NET Core2.1 中出现了一个新的 HttpClientFactory 功能, 它有助于解决开发人员在使用 HttpClient 实例从其应用程序中访问外部 web 资源时可能遇 ...

  2. .Net45下HttpClient的几个缺陷

    前言 最近在写WebClientApi这个组件,底层使用HttpClient,发现HttpClient有许多低级的错误,使用者一不小心就可能会正常的去调用它的这些错误,得不到预期的结果.本文我把我认为 ...

  3. 关于微软HttpClient使用,避免踩坑

    最近公司对于WebApi的场景使用也越来越加大了,随之而来就是Api的客户端工具我们使用哪个?我们最常用的估计就是HttpClient,在微软类库中命名空间地址:System.Net.Http,是一个 ...

  4. .NET Core 迁移躺坑记续集--Win下莫名其妙的超时

    继上一集里说到遇到的各种问题并且弄了n个解决方案之后,特别是对于问题4的解决方案对于切换了HttpClientFactory 我用了你家netcore 2.1下专门解决之前HttpClient口病已久 ...

  5. HttpClient总结一之基本使用

    最近工作中是做了一个handoop的hdfs系统的文件浏览器的功能,是利用webhdfs提供的rest api来访问hdfs来与hdfs进行交互的,其中大量使用HttpClient,之前一直很忙,没什 ...

  6. 利用httpclient和多线程刷訪问量代码

    缘起于玩唱吧,由于唱吧好友少,訪问量低,又不想加什么亲友团之类的,主要是太麻烦了,于是我就琢磨唱吧的訪问机制,准备用java的httpclient库来进行刷訪问量,想到动态IP反复使用就想到了用多线程 ...

  7. [Python网络编程]gevent httpclient以及网页编码

    之前看到geventhttpclient这个项目,https://github.com/gwik/geventhttpclient,官方文档说非常快,因为响应使用了C的解析,所以我一直想把这玩意用到项 ...

  8. 使用angular的HttpClient搭配rxjs

    一.原Http使用总结 使用方法 在根模块或核心模块引入HttpModule 即在AppModule或CoreModule中引入HttpModule: import { HttpModule } fr ...

  9. 如何使用HttpClient认证机制

    1.服务器认证(Server Authentication)HttpClient处理服务器认证几乎是透明的,仅需要开发人员提供登录信息(login credentials).登录信息保存在HttpSt ...

随机推荐

  1. Android的init过程:init.rc解析流程

    这几天打算看下安卓的代码,看优秀的源代码也是一种学习过程,看源代码的过程就感觉到,安卓确实是深受linux内核的影响,不少数据结构的使用方法全然一致.花了一中午时间,研究了下init.rc解析过程,做 ...

  2. ajax初探--实现简单实时验证

    学习技术最好的方式就是在做中学,做一个小demo来对前端输入进行实时验证. 利用ajax技术和Sevlet技术来实现,使用原生的js. 源码可访问,我的Github 什么是ajax Ajax 即&qu ...

  3. nat的翻译类型(3)--端口地址转换

    目的:在1.1 1.2 1.3 三台内网的服务器访问外网的服务器(202.1.1.2)时,将内网ip转换为外网ip. 1.设置内网三台服务器的Ip ,网关,以及外网服务器的ip网关 分别为:192.1 ...

  4. 工厂方法模式的一些思考(java语法表示)

    同为创造型设计模式的简单工厂模式可以理解为对new关键字的代替. 本着重复三次即重构的原则,如果一个对象在不同的地方被new了两次以上,那就可以考虑使用它.那我们为什么要用简单工厂模式代替new呢?就 ...

  5. js判断一些时间范围是否有重复时间段

    function isHasRepeatTime(data) { var startTimeArr = []; var endTimeArr = []; (data || []).map(functi ...

  6. 使用docker+consul+nginx集成分布式的服务发现与注册架构

    一.环境说明: 1.一台虚拟机,该系统已经装好了docker: ip 192.168.10.224 虚拟网卡,与主机互通 操作系统rhel6 内核 2.6.32  64位 docker版本 1.7.1 ...

  7. [.Net跨平台]部署DTCMS到Jexus遇到的问题及解决思路---Linux环境搭建

    最近朋友托我帮忙研究如何把一个DTCMS部署到Linux下,经过1天的研究,部署基本成功,可能有些细节还未注意到,现在把心得分享一下.过程比预期的要简单 身为.Net程序员,这个问题的第一步可能就是如 ...

  8. 【java】用HashMap计数,用TreeSet排序

    package com.tn.hashMap; import java.util.HashMap; import java.util.TreeSet; public class HashMapDemo ...

  9. OC学习10——内存管理

    1.对于面向对象的语言,程序需要不断地创建对象.这些对象都是保存在堆内存中,而我们的指针变量中保存的是这些对象在堆内存中的地址,当该对象使用结束之后,指针变量指向其他对象或者指向nil时,这个对象将称 ...

  10. ActiveMQ (一) 初识ActiveMQ

    了解JMS JMS即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进 ...