.NET 5.0使用HttpClient调用外部API响应极慢如何优化
问题解决方案
第一步 修复代码中的明显错误
- 删掉冗余的构造函数:你同时声明了Typed Client专属的
HttpClient参数构造,和基于命名客户端的IHttpClientFactory参数构造,DI注入时构造选择逻辑冲突会导致HttpClient实例初始化异常,直接保留带HttpClient参数的构造即可,删除IHttpClientFactory相关的构造代码。 - 修正返回类型不匹配问题:方法定义的返回值是
Task<Holiday>,但反序列化时解析的是List<Holiday>集合,类型不匹配会触发反序列化异常,你设置了无限超时后异常会被挂住或触发静默重试,将方法返回值修改为Task<List<Holiday>>即可。 - 修正URL拼接错误:方法传入的
country和year参数未生效,且字符串嵌套双引号写法错误,替换为正确的插值字符串写法:
string url = $"/holidays?accesskey=MyAccessKey&secretkey=MySecretKey&version=3&country={country}&year={year}&lang=en";
第二步 优化HttpClient配置解决响应慢问题
- 补充标准请求头:多数公开API会校验
User-Agent、Accept等请求头,缺失符合要求的头会被故意延迟响应或拦截,在Startup中注册HttpClient时添加模拟浏览器的请求头,同时设置合理的超时时间,删除代码中手动设置的无限超时配置:
services.AddHttpClient<IHolidayService, HolidayService>("PublicHolidaysApi", c => { c.BaseAddress = new Uri("https://api.xmltime.com"); // 模拟浏览器User-Agent c.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); c.DefaultRequestHeaders.Accept.ParseAdd("application/json"); // 设置合理超时,10秒完全满足正常请求 c.Timeout = TimeSpan.FromSeconds(10); });
- 禁用自动代理检测:HttpClient默认会自动检测系统代理,无代理配置时代理检测流程会耗时数分钟到数十分钟,在注册HttpClient时添加 handler 配置关闭代理:
services.AddHttpClient<IHolidayService, HolidayService>("PublicHolidaysApi", c => { // 上述基础配置保持不变 }) .ConfigurePrimaryHttpMessageHandler(() => { return new HttpClientHandler { UseProxy = false, // 若接口无证书校验问题可添加此行跳过证书校验,进一步减少耗时 ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true }; });
第三步 简化业务代码
删除冗余的无限超时CancellationTokenSource配置,优化后的业务方法如下:
public async Task<List<Holiday>> GetHolidays(string country,int year) { string url = $"/holidays?accesskey=MyAccessKey&secretkey=MySecretKey&version=3&country={country}&year={year}&lang=en"; var response = await _client.GetAsync(url).ConfigureAwait(false); if (response.IsSuccessStatusCode) { using var responseStream = await response.Content.ReadAsStreamAsync(); // 添加大小写不敏感配置,避免字段名大小写不匹配导致反序列化失败 return await JsonSerializer.DeserializeAsync<List<Holiday>>(responseStream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); } throw new HttpRequestException(response.ReasonPhrase); }
内容的提问来源于stack exchange,提问作者hanu
相关产品推荐
相关产品推荐

