正确使用 HttpClient
2023-03-31 10:56:10 时间
正确使用 HttpClient
其实标题应该叫:在控制台程序中使用IHttpClientFactory
以前一直使用的是HttpWebRequest,.NET6工程代码提示已过时,使用HttpClient代替,所以尝试使用HttpClient。经过几天的学习探索,基本掌握了HttpClient的使用方法。
由于有时会写控制台程序,所以简单封装了一下(写控制台程序时使用,写Web程序时也可以使用但比较另类,一般不用这种方式,注入的方式请搜索别的博客):
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Utils
{
/// <summary>
/// HttpClient工厂类
/// </summary>
public class HttpClientFactory
{
private static readonly IHttpClientFactory _httpClientFactory;
static HttpClientFactory()
{
ServiceCollection serviceCollection = new ServiceCollection();
ServiceProvider serviceProvider = serviceCollection.AddHttpClient().BuildServiceProvider();
_httpClientFactory = serviceProvider.GetService<IHttpClientFactory>();
}
public static HttpClient GetClient()
{
return _httpClientFactory.CreateClient();
}
}
}
如何使用
string url = "http://192.168.31.11:5028/Test/Get";
HttpClient httpClient = HttpClientFactory.GetClient();
string strResult = await (await httpClient.GetAsync(url)).Content.ReadAsStringAsync();
在控制台程序中使用IHttpClientFactory
需要通过NuGet搜索安装下面两个包:
Microsoft.Extensions.Http
Microsoft.Extensions.DependencyInjection
然后使用上述代码
注意事项
HttpClient虽然有Dispose方法,但千万不要调用Dispose,也千万不要使用using语句,否则会产生大量TIME_WAIT(因为Socket连接等一段时间才会释放),端口用完可就要报错了!
也不要使用全局单例HttpClient,因为这种方式不支持DNS变更。
参考博客
https://www.cnblogs.com/yakniu/p/16331179.html
http://www.manongjc.com/detail/29-vhvbqzxwhlunudu.html
https://www.bilibili.com/read/cv11776829/
======== 以下是旧代码 ===================================================================================================
根据评论所述,下述旧工厂类代码存在的问题
- 没有解决DNS过期的问题
- 不能限制默认访问头,可能被修改
- HttpClient池大小设置成多少也是个问题
使用 HttpClient 注意事项
- HttpClient默认最大并发连接数是2
- 本机测试(被请求的WebApi部署在本机)HttpClient不会被限制最大并发连接数
- 使用HttpClient要写个工厂类,因为HttpClient不能频繁创建
- HttpClient类提供的方法是线程安全的
HttpClient 工厂类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Factory
{
/// <summary>
/// HttpClient工厂类
/// 注意:
/// 1. HttpClient默认最大并发连接数是2
/// 2. 本机测试HttpClient不会被限制最大并发连接数
/// </summary>
public class HttpClientFactory
{
private int _httpClientCount;
private readonly HttpClient[] _httpClientArray;
private int _index = -1;
private readonly object _lock = new object();
private static readonly HttpClientFactory _instance = new HttpClientFactory();
public static HttpClientFactory Instance
{
get
{
return _instance;
}
}
public HttpClientFactory(int httpClientCount = 50)
{
_httpClientCount = httpClientCount;
_httpClientArray = new HttpClient[_httpClientCount];
for (int i = 0; i < _httpClientCount; i++)
{
_httpClientArray[i] = new HttpClient();
}
}
public HttpClient Get()
{
lock (_lock)
{
_index++;
if (_index == _httpClientCount)
{
_index = 0;
}
return _httpClientArray[_index];
}
}
}
}
如何使用
string url = "http://192.168.31.11:5028/Test/Get";
HttpClient httpClient = HttpClientFactory.Instance.Get();
string strResult = await (await httpClient.GetAsync(url)).Content.ReadAsStringAsync();
相关文章
- 深入探讨Java中的异常与错误处理
- 研究学习Kotlin的一些方法
- 数据显示Java热度持续下落,日子屈指可数?
- 2017年5月编程语言排行榜:Java与C语言优势正开始缩小
- Java多线程之内置锁与显示锁
- Java线程池的理论与实践
- 白话阿里巴巴Java开发手册(编程规约)
- 关于Java你不知道的十件事
- Java服务化系统线上应急和技术攻关,你必须掌握的Linux命令
- Java实现高斯模糊和图像的空间卷积
- Java阻塞队列实现原理分析
- NPM使用技巧
- Node.js对Java开发者而言是什么?
- Java反射机制应用实践
- 理解RxJava中的Single和Completable
- 2017年你不能错过的Java类库
- 大规模集群下的Hadoop NameNode
- 从源码解密Spark内存管理
- 2017年3月编程语言排行榜:Swift首次进入前十
- JVM热点技术:Java类的加载机制