HttpClient到底该不该using?
HttpClient实例是否应该释放掉?
从源代码中可以的看到httpClient类最上层实现了IDisposable接口,看到该接口我们下意识就是要用using(自动释放)代码块包含起、或者自己手动调用Disposable方法释放。
如:
using(var conn = new SqlConnection(connStr))
{ }
这种使用方式是十分正确的,但是由于SqlConnection是比较特殊,这里程序并不会真正的把Connection给释放掉,而是把它丢进连接池(ConnectionPool)中,后面使用的时候在取出来。
所以这时候问题就来了,httpClient并没有ConnectionPool实现,所以当我们Disposables时它会以 TIME_WAIT的状态继续存活240秒,当程序在短时间内大量创建httpClient对象并销毁时,会占用过多的系统内容,严重的还有可能会消耗完socket port,导致无法建立新的连接。所以我们应该重复使用httpClient对象。
这句话来自官网: HttpClient用于在应用程序的整个生存期内实例化一次并重复使用。 实例化每个请求的 HttpClient 类将耗尽重负载下可用的插槽数。 这将导致 SocketException 错误。 下面是正确使用 HttpClient 的示例。
public class GoodController : ApiController
{
private static readonly HttpClient HttpClient; static GoodController()
{
HttpClient = new HttpClient();
}
}
共用一个 HttpClient 实例的副作用
共用静态HttpClient 可共用连线避免TIME_WAIT 连线残留,但这也衍生新问题- 当HttpClient 使用xxx.yyy.zzz DNS 名称连上网站,它会记忆DNS 解析结果,
但因缺乏失效机制快取将永久有效,若DNS 记录修改,必须重新启动程序才会重新解析DNS 取得新IP。在一些实务情境,程式可没法说重启就重启,
针对此有个简单解法是对特定网站指定 ConnectionLeaseTimeout,强迫 .NET 在一段时间后关闭连线,下次重建连线将可重新解析 DNS。
var sp = ServicePointManager.FindServicePoint(new Uri("http://xxx.yyy.zzz"));
sp.ConnectionLeaseTimeout = *; // 10min
结论:
对于httpClient实例不要Disposable(),应该用一个静态变量把它储存起来,供其它地方使用。
最新文章
- iOS多线程之9.自定义NSOperation
- 基于Spring4+Hibernate4的通用数据访问层+业务逻辑层(Dao层+Service层)设计与实现!
- js控制全屏窗口
- new一个数组,delete释放内存
- 学习笔记——Maven实战(一)坐标规划
- MySQL查询表内重复记录
- Dev GridView 获取选中分组下的所有数据行 z
- 代码片段 - JavaScript 求时间差
- swfupload用法总结
- ZOJ3527
- 照葫芦画瓢系列之Java --- Maven的配置
- SQL Server2012中如何通过bak文件还原SQL Server2012数据库
- Spring AOP详解和实现方式
- OpenCV轮廓vectorvector
- tomcat6url请求400错误(%2F与%5C)
- uchome 全局变量
- 6-11 Level-order Traversal(25 分)
- #leetcode刷题之路19-删除链表的倒数第N个节点
- doppia代码结构
- 【题解】洛谷P1350 车的放置(矩阵公式推导)