错误的使用HttpClient()
using(var client = new HttpClient())
using (var client = new System.Net.Http.HttpClient())
{
var result = await client.GetStringAsync(url);
...
...
}
- 这种方式会导致TCP连接在项目运行结束后依然存在,状态为“TIME_WAIT”,这会占用系统资源,尤其是在高并发的情况下,可能会导致socket资源耗尽,从而引发错误。
-
错误原因
- 频繁开启与关闭网络连接会影响性能。
HttpClient
调用其Dispose
方法时,并不能立即释放底层的socket资源,这可能导致程序因耗尽连接资源而出现问题。如何使用IHttpClientFactory
- 在.NET Core 2.1及更高版本中,可以通过依赖注入(DI)框架注入
IHttpClientFactory
:services.AddControllers(); services.AddHttpClient();
例如一个简单的Web API 控制宿主
classProgram
static void Main(string[] args)
vargreetingServiceaddress=
newUri("http://localhost:50650/api/greeting");
varclient=newHttpClient();
var result = client.GetAsync(greetingServiceAddress).Result;
var greeting = result.Content.ReadAsStringAsync().Result;
Consolewriteline(greeting)
应该使用IHttpClientFactory
来管理HttpClient
的创建和生命周期。
1.配置服务:在你的Startup.cs
文件中(或者在.NET Core 3.x及更高版本中的Program.cs
中),配置IHttpClientFactory
。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpClient();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
2.使用IHttpClientFactory
:在你的控制器或服务中,注入IHttpClientFactory
并使用它来创建HttpClient
。
public class GreetingService
{
private readonly IHttpClientFactory _clientFactory;
private readonly Uri _greetingServiceAddress;
public GreetingService(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
_greetingServiceAddress = new Uri("http://localhost:50650/api/greeting");
}
public async Task<string> GetGreetingAsync()
{
var client = _clientFactory.CreateClient();
var result = await client.GetAsync(_greetingServiceAddress);
result.EnsureSuccessStatusCode();
var greeting = await result.Content.ReadAsStringAsync();
return greeting;
}
}
3.调用服务:在你的Main
方法或其他地方调用GetGreetingAsync
方法。
class Program
{
static async Task Main(string[] args)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var serviceProvider = serviceCollection.BuildServiceProvider();
var greetingService = serviceProvider.GetService<GreetingService>();
var greeting = await greetingService.GetGreetingAsync();
Console.WriteLine(greeting);
}
private static void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHttpClient();
}
}
说明:
- 服务配置:在
ConfigureServices
方法中,通过调用services.AddHttpClient()
来注册IHttpClientFactory
。 - 使用
IHttpClientFactory
:在GreetingService
中,注入IHttpClientFactory
并使用它来创建一个HttpClient
实例。这样可以确保HttpClient
的生命周期被正确管理,避免了资源耗尽的问题。 - 异步调用:使用
async/await
来异步调用GetGreetingAsync
方法,这样可以避免阻塞线程。
通过这种方式,你的应用程序将更有效地管理网络资源,并减少因资源耗尽而导致的问题。