.NET Core Web应用Test方法并行调用时HttpClient POST请求是否并行执行?
问题解答
1. 请求执行逻辑说明
- 当Test方法被并行调用10次时,理论上发往远程服务器的POST请求会并行发起,但你当前的代码存在多处设计缺陷,会导致实际运行中出现串行阻塞、连接超时等异常,和你预期的并行效果不符。
2. 现有代码的核心问题
2.1 HttpClient使用方式错误
- .NET中
HttpClient被设计为单例复用的对象,每次请求都新建HttpClient会导致底层TCP连接无法复用,请求结束后连接会进入TIME_WAIT状态,大量请求时会快速耗尽服务器可用端口,同时新建TCP连接的开销会大幅提升请求耗时,甚至直接触发连接超时。
2.2 同步阻塞导致线程池耗尽
- 你用
Task.Run()+Wait()/.Result的写法强行把异步API转为同步调用,在高并发场景下会快速耗尽ASP.NET Core的线程池资源,后续请求只能排队等待空闲线程,直接表现为请求串行执行,最后一个请求的耗时等于前面所有请求的耗时总和。
2.3 默认连接数限制
- .NET针对同一域名的HTTP请求默认有连接数限制,未手动调整的情况下高并发请求会被排队,进一步加剧串行阻塞问题。
3. 报错说明
你遇到的报错翻译为:
由于连接方在一段时间后没有正确响应,或已建立的连接失败(因为连接的主机没有响应),连接尝试失败。
这个报错就是前面提到的端口耗尽、连接排队超时、远程服务器连接数超限等问题共同导致的。
4. 优化方案
4.1 复用HttpClient实例
- 在ASP.NET Core中推荐通过DI注入
IHttpClientFactory来创建HttpClient,自动实现连接复用和生命周期管理,避免手动管理单例的问题。
4.2 改为全异步实现
把同步方法改为异步版本,彻底避免阻塞线程池:
public async Task<T> PostReadAsync<T>(string baseAddress, string url, out bool succeded, object entity = null) { T returnValue = default(T); succeded = false; try { // _httpClient是通过IHttpClientFactory注入的复用实例 _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", MyApiKey); string json = JsonConvert.SerializeObject(entity); var body = new StringContent(json, Encoding.UTF8, "application/json"); using var res = await _httpClient.PostAsync($"{baseAddress}/{url}", body); succeded = res.IsSuccessStatusCode; if (succeded) { var responseStr = await res.Content.ReadAsStringAsync(); returnValue = JsonConvert.DeserializeObject<T>(responseStr); } else { Log($"PostRead failed, error: {JsonConvert.SerializeObject(res)}"); } } catch (Exception ex) { Log($"PostRead error: {baseAddress}/{url} entity: {JsonConvert.SerializeObject(entity)}"); } return returnValue; }
4.3 调整连接数限制
- 可以在配置HttpClient时调整同一域名的最大连接数,避免请求排队:
services.AddHttpClient("RemoteApi", client => { client.DefaultRequestHeaders.Add("Accept", "application/json"); }) .SetHandlerLifetime(TimeSpan.FromMinutes(5)) .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { MaxConnectionsPerServer = 100 // 根据实际场景调整 });
内容的提问来源于stack exchange,提问作者markzzz
相关产品推荐
相关产品推荐

