|
此文章由 DDD888 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 DDD888 所有!转贴必须注明作者、出处和本声明,并保持内容完整
下面的描述太可怕了,我肯定是用了许多GetHttpClient1这样的代码,我一直以为这是标准代码,让我去共享static GetHttpClient2的方式我肯定是做不到的
____________________________________________________________________________________
HttpClient
未正确使用 HttpClient 可能会导致资源泄漏。 系统资源(如数据库连接、套接字、文件句柄等):
比内存更短缺。
在泄漏时出现的问题比内存更多。
经验丰富的 .NET 开发人员知道要对实现 IDisposable 的对象调用 Dispose。 未释放实现 IDisposable 的对象通常会导致内存泄漏或系统资源泄漏。
HttpClientIDisposable实现,但不应在每个调用上释放。 而是应重用 HttpClient。
下面的终结点会对每个请求创建并释放新的 HttpClient 实例:
C#
复制
[HttpGet("httpclient1")]
public async Task<int> GetHttpClient1(string url)
{
using (var httpClient = new HttpClient())
{
var result = await httpClient.GetAsync(url);
return (int)result.StatusCode;
}
}
在负载下,记录了以下错误消息:
复制
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLG70PBE1CR1", Request id "0HLG70PBE1CR1:00000031":
An unhandled exception was thrown by the application.
System.Net.Http.HttpRequestException: Only one usage of each socket address
(protocol/network address/port) is normally permitted --->
System.Net.Sockets.SocketException: Only one usage of each socket address
(protocol/network address/port) is normally permitted
at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port,
CancellationToken cancellationToken)
即使释放了 HttpClient 实例,实际网络连接也需要一些时间才能由操作系统释放。 持续创建新连接时,会发生端口耗尽。 每个客户端连接都需要自己的客户端端口。
防止端口耗尽的一种方法是重用同一个 HttpClient 实例:
C#
复制
private static readonly HttpClient _httpClient = new HttpClient();
[HttpGet("httpclient2")]
public async Task<int> GetHttpClient2(string url)
{
var result = await _httpClient.GetAsync(url);
return (int)result.StatusCode;
}
HttpClient 实例会在应用停止时释放。 此示例演示并非每个可释放资源都应在每次使用后释放。 |
|