使用IHttpClientFactory来管理HttpClient的创建和生命周期

错误的使用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方法,这样可以避免阻塞线程。

通过这种方式,你的应用程序将更有效地管理网络资源,并减少因资源耗尽而导致的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值