.NET 10了,HttpClient还是不能用using吗?我做了一个实验
会突然变成玄学有的人能跑有的人会炸有人说这是一个这是一个“bug”在某某版本中会修复其实并没有有人说这是一个feature设计就是如此……所以我决定做一个实验来重现一下10年前就有的现象看这些现象是否有任何不同。本文用一组可复现的压测同机 server/clientWindowsrequests20000parallel200对比每请求new HttpClientDispose()也就是大家常说的“using 写法”复用一个HttpClient静态/单例使用IHttpClientFactory并观察关键指标TIME_WAIT 数量以及是否出现经典的端口耗尽错误通常每个套接字地址(协议/网络地址/端口)只允许使用一次。实验目标验证“每请求 new HttpClient 并 using 释放”在高并发下会导致 TIME_WAIT 激增并对比复用 HttpClient / IHttpClientFactory 的表现。实验环境与参数OS: WindowsSDK: .NET SDK 10.0.102服务器: HttpLeakServertarget net6通过 roll-forward 运行客户端: net48 / net6 / net8 / net10压测参数: requests20000, parallel200, timeoutSeconds5TIME_WAIT 统计:netstat -an过滤端口 5055隔离策略: 每轮结束后等待 TIME_WAIT baseline 200每 10 秒检查最长 300 秒如何运行可复现完整项目我放在 GitHubhttps://github.com/sdcb/http-client-exp1启动服务端单独窗口dotnet run --project Server/HttpLeakServer/HttpLeakServer.csproj2运行实验脚本另一个窗口scripts/run-experiment-external-server.ps1本次日志目录logs/run-20260119-095017解读为什么“using HttpClient”会把你推向端口耗尽很多人直觉会觉得HttpClient是托管对象用完Dispose()不就释放资源了吗但这里有两个关键点经常被忽略HttpClient并不是“请求一次就关一次连接”的简单模型。HTTP Keep-Alive 连接池的存在意味着正确姿势应该是复用底层连接或至少复用 handler 的连接池让大量请求复用少量 TCP 连接。你频繁new HttpClientDispose()等价于频繁建立 TCP 连接并快速关闭。而 TCP 连接的关闭会进入TIME_WAIT具体哪一端进入 TIME_WAIT 与关闭时序有关TIME_WAIT 存在的意义是保护网络不被“旧连接的残留包”污染。在“200 并发 2 万次请求”这种参数下如果你让每个请求都创建新连接那么很容易短时间制造大量 TIME_WAIT一旦本机可用的临时端口范围被 TIME_WAIT 占满或接近占满新连接就会开始失败典型异常就是通常每个套接字地址(协议/网络地址/端口)只允许使用一次。这也是为什么同样的代码在低并发下“看起来完全没问题”在压力一上来就开始“玄学报错”那到底怎么写才对本文不展开“所有场景的最佳实践”只给两条最能落地的结论业务代码不要每次请求 new HttpClient。要么复用单例/静态HttpClient要么使用IHttpClientFactory。可以 using 的是HttpResponseMessage/HttpContent它们确实应该及时释放而不是“每个请求一个 HttpClient”。下面我把这次实验的完整代码和原始日志全部贴出来方便你自己复跑/改参数/做二次验证。完整代码精简版一份源码 条件编译完整项目地址https://github.com/sdcb/http-client-exp为了避免同样的代码贴四遍这里把 net48/net6/net8/net10 的客户端合并成一份用#if / #elif表示差异实验输出与原始日志仍按“多份结果”原样保留在后文。简单服务端HttpLeakServerServer/HttpLeakServer/HttpLeakServer.csprojProject SdkMicrosoft.NET.Sdk.Web PropertyGroup TargetFrameworknet6.0/TargetFramework Nullableenable/Nullable ImplicitUsingsenable/ImplicitUsings /PropertyGroup /ProjectServer/HttpLeakServer/Program.csusing Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; var builder WebApplication.CreateBuilder(args); builder.Logging.ClearProviders(); builder.Logging.AddSimpleConsole(options { options.SingleLine true; options.TimestampFormat HH:mm:ss ; }); var app builder.Build(); app.MapGet(/, () Results.Text(ok)); app.MapGet(/ping, () Results.Text(ok)); app.MapGet(/slow, async () { await Task.Delay(50); return Results.Text(ok); }); var url Environment.GetEnvironmentVariable(HTTPLEAK_URL) ?? http://localhost:5055; app.Urls.Add(url); app.Lifetime.ApplicationStarted.Register(() { Console.WriteLine($Listening on {url}); }); await app.RunAsync();客户端HttpLeakClientnet48/net6/net8/net10 共用一份Clients/HttpLeakClient/HttpLeakClient.csproj示意多目标 条件依赖Project SdkMicrosoft.NET.Sdk PropertyGroup OutputTypeExe/OutputType TargetFrameworksnet48;net6.0;net8.0;net10.0/TargetFrameworks LangVersionlatest/LangVersion Nullableenable/Nullable ImplicitUsingsenable/ImplicitUsings /PropertyGroup ItemGroup Condition$(TargetFramework) net48 Reference IncludeSystem.Net.Http / /ItemGroup ItemGroup Condition$(TargetFramework) net10.0 PackageReference IncludeMicrosoft.Extensions.Http Version10.0.0 / /ItemGroup /ProjectClients/HttpLeakClient/Program.cs用#if表示差异using System.Diagnostics; using System.Net.Http; #if NET48 using System.Net; #endif #if NET10_0_OR_GREATER using Microsoft.Extensions.DependencyInjection; #endif static string? GetArg(string[] args, string name) { for (var i 0; i args.Length - 1; i) { if (string.Equals(args[i], name, StringComparison.OrdinalIgnoreCase)) { return args[i 1]; } } return null; } static int GetArgInt(string[] args, string name, int defaultValue) { var value GetArg(args, name); return int.TryParse(value, out var parsed) ? parsed : defaultValue; } var url GetArg(args, --url) ?? http://localhost:5055/ping; var requests GetArgInt(args, --requests, 20000); var parallel GetArgInt(args, --parallel, 200); var logEvery GetArgInt(args, --logEvery, 1000); var timeoutSeconds GetArgInt(args, --timeoutSeconds, 5); #if NET10_0_OR_GREATER var mode GetArg(args, --mode) ?? new; // new | static | factory #endif Console.WriteLine($url{url}); #if NET10_0_OR_GREATER Console.WriteLine($requests{requests}, parallel{parallel}, timeoutSeconds{timeoutSeconds}, mode{mode}); #else Console.WriteLine($requests{requests}, parallel{parallel}, timeoutSeconds{timeoutSeconds}); #endif #if NET48 ServicePointManager.DefaultConnectionLimit 1000; ServicePointManager.Expect100Continue false; #endif var throttler new SemaphoreSlim(parallel); var tasks new ListTask(requests); var sw Stopwatch.StartNew(); var success 0; var failed 0; #if NET10_0_OR_GREATER HttpClient? staticClient null; if (string.Equals(mode, static, StringComparison.OrdinalIgnoreCase)) { staticClient new HttpClient { Timeout TimeSpan.FromSeconds(timeoutSeconds) }; } IHttpClientFactory? httpClientFactory null; ServiceProvider? serviceProvider null; if (string.Equals(mode, factory, StringComparison.OrdinalIgnoreCase)) { var services new ServiceCollection(); services.AddHttpClient(); serviceProvider services.BuildServiceProvider(); httpClientFactory serviceProvider.GetRequiredServiceIHttpClientFactory(); } #endif for (var i 0; i requests; i) { await throttler.WaitAsync(); var index i 1; tasks.Add(Task.Run(async () { try { #if NET10_0_OR_GREATER HttpClient client; if (staticClient ! null) { client staticClient; } else if (httpClientFactory ! null) { client httpClientFactory.CreateClient(); client.Timeout TimeSpan.FromSeconds(timeoutSeconds); } else { client new HttpClient(); client.Timeout TimeSpan.FromSeconds(timeoutSeconds); } using var response await client.GetAsync(url); response.EnsureSuccessStatusCode(); Interlocked.Increment(ref success); if (staticClient null httpClientFactory null) { client.Dispose(); } #else using var client new HttpClient(); client.Timeout TimeSpan.FromSeconds(timeoutSeconds); using var response await client.GetAsync(url); response.EnsureSuccessStatusCode(); Interlocked.Increment(ref success); #endif } catch (Exception ex) { var fail Interlocked.Increment(ref failed); if (fail 5) { Console.WriteLine($ERR#{fail}: {ex.GetType().Name} {ex.Message}); } } finally { throttler.Release(); } })); if (index % logEvery 0) { Console.WriteLine($queued: {index}/{requests}, success: {Volatile.Read(ref success)}, failed: {Volatile.Read(ref failed)}, elapsed: {sw.Elapsed}); } } await Task.WhenAll(tasks); Console.WriteLine($done: success{success}, failed{failed}, elapsed{sw.Elapsed}); #if NET10_0_OR_GREATER staticClient?.Dispose(); serviceProvider?.Dispose(); #endifPowerShell 脚本脚本我就不在文章里全文贴了外部启动 Server 版本https://github.com/sdcb/http-client-exp/blob/main/scripts/run-experiment-external-server.ps1脚本内启动 Server 版本https://github.com/sdcb/http-client-exp/blob/main/scripts/run-experiment.ps1原始实验结果日志完整贴出日志目录logs/run-20260119-095017experiment-summary.log[2026-01-19T09:51:13.718085708:00] net48 ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net48.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net48.err.log [2026-01-19T09:53:33.036252308:00] net6 ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net6.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net6.err.log [2026-01-19T09:56:00.457452708:00] net8 ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net8.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net8.err.log [2026-01-19T09:58:27.261813908:00] net10-new ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-new.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-new.err.log [2026-01-19T10:00:53.049047208:00] net10-static ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-static.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-static.err.log [2026-01-19T10:01:10.209616408:00] net10-factory ExitCode0 OutLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-factory.out.log ErrLogC:\Users\ZhouJie\source\repos\http-client-exp\logs\\run-20260119-095017\net10-factory.err.lognetstat.log[2026-01-19T09:50:55.662745508:00] before-net48 TIME_WAIT2 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:51:15.468660308:00] after-net48 TIME_WAIT20002 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:53:13.964748508:00] before-net6 TIME_WAIT0 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:53:33.811229408:00] after-net6 TIME_WAIT20000 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:55:42.643501508:00] before-net8 TIME_WAIT0 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:56:01.190000008:00] after-net8 TIME_WAIT18361 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:58:08.860312908:00] before-net10-new TIME_WAIT0 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T09:58:28.150073708:00] after-net10-new TIME_WAIT18860 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T10:00:36.103875708:00] before-net10-static TIME_WAIT0 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T10:00:53.100725908:00] after-net10-static TIME_WAIT200 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T10:00:53.245879808:00] before-net10-factory TIME_WAIT200 ESTABLISHED0 CLOSE_WAIT0 [2026-01-19T10:01:10.257467808:00] after-net10-factory TIME_WAIT200 ESTABLISHED0 CLOSE_WAIT0cooldown.log[2026-01-19T09:51:16.268766608:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:51:27.042780508:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:51:37.818438208:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:51:48.540449208:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:51:59.284696808:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:52:10.156207908:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:52:21.058862208:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:52:31.777770408:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:52:42.566435008:00] cooldown-net48 TIME_WAIT20002 baseline2 limit202 [2026-01-19T09:52:53.329961408:00] cooldown-net48 TIME_WAIT20001 baseline2 limit202 [2026-01-19T09:53:03.810973408:00] cooldown-net48 TIME_WAIT10752 baseline2 limit202 [2026-01-19T09:53:13.856083108:00] cooldown-net48 TIME_WAIT0 baseline2 limit202 [2026-01-19T09:53:34.637071108:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:53:45.516697408:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:53:56.289973608:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:54:07.016542808:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:54:17.887213708:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:54:28.767352908:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:54:39.520009108:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:54:50.309065908:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:55:01.063892008:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:55:11.752952808:00] cooldown-net6 TIME_WAIT20000 baseline0 limit200 [2026-01-19T09:55:22.388644508:00] cooldown-net6 TIME_WAIT12540 baseline0 limit200 [2026-01-19T09:55:32.465878608:00] cooldown-net6 TIME_WAIT435 baseline0 limit200 [2026-01-19T09:55:42.535487808:00] cooldown-net6 TIME_WAIT0 baseline0 limit200 [2026-01-19T09:56:01.887649308:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:56:12.634154108:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:56:23.280660408:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:56:33.942587308:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:56:44.627756108:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:56:55.301367408:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:57:06.027812808:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:57:16.731557808:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:57:27.388792508:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:57:38.044245308:00] cooldown-net8 TIME_WAIT18361 baseline0 limit200 [2026-01-19T09:57:48.656683908:00] cooldown-net8 TIME_WAIT12989 baseline0 limit200 [2026-01-19T09:57:58.734733708:00] cooldown-net8 TIME_WAIT1069 baseline0 limit200 [2026-01-19T09:58:08.778066008:00] cooldown-net8 TIME_WAIT0 baseline0 limit200 [2026-01-19T09:58:29.026129108:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:58:39.749104308:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:58:50.461379608:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:01.206454508:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:11.871015308:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:22.564848608:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:33.275595808:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:43.963154708:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T09:59:54.697924308:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T10:00:05.396139708:00] cooldown-net10-new TIME_WAIT18860 baseline0 limit200 [2026-01-19T10:00:15.860737808:00] cooldown-net10-new TIME_WAIT11840 baseline0 limit200 [2026-01-19T10:00:25.947140708:00] cooldown-net10-new TIME_WAIT614 baseline0 limit200 [2026-01-19T10:00:36.011170108:00] cooldown-net10-new TIME_WAIT0 baseline0 limit200 [2026-01-19T10:00:53.151064908:00] cooldown-net10-static TIME_WAIT200 baseline0 limit200 [2026-01-19T10:01:10.305778508:00] cooldown-net10-factory TIME_WAIT200 baseline200 limit400net48.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5 queued: 1000/20000, success: 803, failed: 0, elapsed: 00:00:00.7170409 queued: 2000/20000, success: 1803, failed: 0, elapsed: 00:00:01.5455465 queued: 3000/20000, success: 2800, failed: 0, elapsed: 00:00:02.3559601 queued: 4000/20000, success: 3801, failed: 0, elapsed: 00:00:03.1925172 queued: 5000/20000, success: 4802, failed: 0, elapsed: 00:00:04.0184093 queued: 6000/20000, success: 5802, failed: 0, elapsed: 00:00:04.8348862 queued: 7000/20000, success: 6800, failed: 0, elapsed: 00:00:05.6775563 queued: 8000/20000, success: 7801, failed: 0, elapsed: 00:00:06.5458377 queued: 9000/20000, success: 8802, failed: 0, elapsed: 00:00:07.4397727 queued: 10000/20000, success: 9803, failed: 0, elapsed: 00:00:08.3348468 queued: 11000/20000, success: 10802, failed: 0, elapsed: 00:00:09.2035416 queued: 12000/20000, success: 11804, failed: 0, elapsed: 00:00:10.0393223 queued: 13000/20000, success: 12806, failed: 0, elapsed: 00:00:10.8262272 queued: 14000/20000, success: 13804, failed: 0, elapsed: 00:00:11.6636597 queued: 15000/20000, success: 14802, failed: 0, elapsed: 00:00:12.4799716 queued: 16000/20000, success: 15819, failed: 0, elapsed: 00:00:13.4697834 queued: 17000/20000, success: 16822, failed: 0, elapsed: 00:00:14.5332049 queued: 18000/20000, success: 17818, failed: 0, elapsed: 00:00:15.5317397 queued: 19000/20000, success: 18816, failed: 0, elapsed: 00:00:16.5405963 queued: 20000/20000, success: 19819, failed: 0, elapsed: 00:00:17.6652081 done: success20000, failed0, elapsed00:00:17.7541839net6.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5 queued: 1000/20000, success: 803, failed: 0, elapsed: 00:00:00.7159800 queued: 2000/20000, success: 1803, failed: 0, elapsed: 00:00:01.6028433 queued: 3000/20000, success: 2802, failed: 0, elapsed: 00:00:02.4876237 queued: 4000/20000, success: 3802, failed: 0, elapsed: 00:00:03.3549543 queued: 5000/20000, success: 4802, failed: 0, elapsed: 00:00:04.2710795 queued: 6000/20000, success: 5801, failed: 0, elapsed: 00:00:05.1637653 queued: 7000/20000, success: 6802, failed: 0, elapsed: 00:00:06.0729777 queued: 8000/20000, success: 7802, failed: 0, elapsed: 00:00:07.0697555 queued: 9000/20000, success: 8801, failed: 0, elapsed: 00:00:08.0143162 queued: 10000/20000, success: 9800, failed: 0, elapsed: 00:00:08.9633860 queued: 11000/20000, success: 10802, failed: 0, elapsed: 00:00:09.9344239 queued: 12000/20000, success: 11802, failed: 0, elapsed: 00:00:10.8379783 queued: 13000/20000, success: 12801, failed: 0, elapsed: 00:00:11.6810601 queued: 14000/20000, success: 13801, failed: 0, elapsed: 00:00:12.5122642 queued: 15000/20000, success: 14800, failed: 0, elapsed: 00:00:13.3692282 queued: 16000/20000, success: 15803, failed: 0, elapsed: 00:00:14.2782829 queued: 17000/20000, success: 16801, failed: 0, elapsed: 00:00:15.2187642 queued: 18000/20000, success: 17802, failed: 0, elapsed: 00:00:16.0811154 queued: 19000/20000, success: 18810, failed: 0, elapsed: 00:00:16.9798536 queued: 20000/20000, success: 19817, failed: 0, elapsed: 00:00:17.8952478 done: success20000, failed0, elapsed00:00:18.0175351net8.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5 queued: 1000/20000, success: 800, failed: 0, elapsed: 00:00:00.8405997 queued: 2000/20000, success: 1802, failed: 0, elapsed: 00:00:01.6913251 queued: 3000/20000, success: 2800, failed: 0, elapsed: 00:00:02.6176324 queued: 4000/20000, success: 3802, failed: 0, elapsed: 00:00:03.4744051 queued: 5000/20000, success: 4801, failed: 0, elapsed: 00:00:04.2873345 queued: 6000/20000, success: 5800, failed: 0, elapsed: 00:00:05.0960137 queued: 7000/20000, success: 6803, failed: 0, elapsed: 00:00:05.8940500 queued: 8000/20000, success: 7802, failed: 0, elapsed: 00:00:06.7207568 queued: 9000/20000, success: 8803, failed: 0, elapsed: 00:00:07.5346954 queued: 10000/20000, success: 9800, failed: 0, elapsed: 00:00:08.3507870 queued: 11000/20000, success: 10802, failed: 0, elapsed: 00:00:09.1985154 queued: 12000/20000, success: 11803, failed: 0, elapsed: 00:00:10.0035216 queued: 13000/20000, success: 12803, failed: 0, elapsed: 00:00:10.7763067 queued: 14000/20000, success: 13802, failed: 0, elapsed: 00:00:11.6251384 queued: 15000/20000, success: 14802, failed: 0, elapsed: 00:00:12.4436652 queued: 16000/20000, success: 15807, failed: 0, elapsed: 00:00:13.3164599 queued: 17000/20000, success: 16801, failed: 0, elapsed: 00:00:14.2231530 ERR#1: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#2: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#3: HttpRequestException 通常每个套接地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#5: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#4: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) queued: 18000/20000, success: 17605, failed: 201, elapsed: 00:00:15.0862152 queued: 19000/20000, success: 17711, failed: 1090, elapsed: 00:00:15.6168905 queued: 20000/20000, success: 18165, failed: 1639, elapsed: 00:00:16.3332350 done: success18361, failed1639, elapsed00:00:16.4268168net10-new.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5, modenew queued: 1000/20000, success: 805, failed: 0, elapsed: 00:00:00.7099803 queued: 2000/20000, success: 1800, failed: 0, elapsed: 00:00:01.5324361 queued: 3000/20000, success: 2800, failed: 0, elapsed: 00:00:02.3573877 queued: 4000/20000, success: 3800, failed: 0, elapsed: 00:00:03.2069000 queued: 5000/20000, success: 4800, failed: 0, elapsed: 00:00:04.0313423 queued: 6000/20000, success: 5802, failed: 0, elapsed: 00:00:04.8687039 queued: 7000/20000, success: 6801, failed: 0, elapsed: 00:00:05.7252572 queued: 8000/20000, success: 7800, failed: 0, elapsed: 00:00:06.5624078 queued: 9000/20000, success: 8800, failed: 0, elapsed: 00:00:07.4244971 queued: 10000/20000, success: 9800, failed: 0, elapsed: 00:00:08.2911306 queued: 11000/20000, success: 10800, failed: 0, elapsed: 00:00:09.1755667 queued: 12000/20000, success: 11801, failed: 0, elapsed: 00:00:10.1160925 queued: 13000/20000, success: 12802, failed: 0, elapsed: 00:00:11.0165038 queued: 14000/20000, success: 13801, failed: 0, elapsed: 00:00:11.9382103 queued: 15000/20000, success: 14802, failed: 0, elapsed: 00:00:12.8002543 queued: 16000/20000, success: 15801, failed: 0, elapsed: 00:00:13.7185127 ERR#3: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#2: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#1: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#5: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) ERR#4: HttpRequestException 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 (localhost:5055) queued: 17000/20000, success: 16682, failed: 118, elapsed: 00:00:14.7578539 queued: 18000/20000, success: 16684, failed: 1118, elapsed: 00:00:15.4297844 queued: 19000/20000, success: 17661, failed: 1140, elapsed: 00:00:16.2796589 queued: 20000/20000, success: 18661, failed: 1140, elapsed: 00:00:17.3258406 done: success18860, failed1140, elapsed00:00:17.3996862net10-static.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5, modestatic queued: 1000/20000, success: 801, failed: 0, elapsed: 00:00:00.6551470 queued: 2000/20000, success: 1800, failed: 0, elapsed: 00:00:01.5355394 queued: 3000/20000, success: 2800, failed: 0, elapsed: 00:00:02.3480456 queued: 4000/20000, success: 3800, failed: 0, elapsed: 00:00:03.0999050 queued: 5000/20000, success: 4800, failed: 0, elapsed: 00:00:03.8470820 queued: 6000/20000, success: 5800, failed: 0, elapsed: 00:00:04.5759884 queued: 7000/20000, success: 6800, failed: 0, elapsed: 00:00:05.3461919 queued: 8000/20000, success: 7801, failed: 0, elapsed: 00:00:06.0916621 queued: 9000/20000, success: 8802, failed: 0, elapsed: 00:00:06.9085343 queued: 10000/20000, success: 9800, failed: 0, elapsed: 00:00:07.8274125 queued: 11000/20000, success: 10800, failed: 0, elapsed: 00:00:08.6757231 queued: 12000/20000, success: 11800, failed: 0, elapsed: 00:00:09.5154490 queued: 13000/20000, success: 12800, failed: 0, elapsed: 00:00:10.3306765 queued: 14000/20000, success: 13800, failed: 0, elapsed: 00:00:11.1493724 queued: 15000/20000, success: 14800, failed: 0, elapsed: 00:00:11.9658212 queued: 16000/20000, success: 15801, failed: 0, elapsed: 00:00:12.7510706 queued: 17000/20000, success: 16800, failed: 0, elapsed: 00:00:13.4735304 queued: 18000/20000, success: 17800, failed: 0, elapsed: 00:00:14.2777953 queued: 19000/20000, success: 18800, failed: 0, elapsed: 00:00:15.0219907 queued: 20000/20000, success: 19801, failed: 0, elapsed: 00:00:15.7699702 done: success20000, failed0, elapsed00:00:15.8507052net10-factory.out.logurlhttp://localhost:5055/ping requests20000, parallel200, timeoutSeconds5, modefactory queued: 1000/20000, success: 801, failed: 0, elapsed: 00:00:00.7094395 queued: 2000/20000, success: 1801, failed: 0, elapsed: 00:00:01.5072383 queued: 3000/20000, success: 2800, failed: 0, elapsed: 00:00:02.3047647 queued: 4000/20000, success: 3800, failed: 0, elapsed: 00:00:03.0607252 queued: 5000/20000, success: 4800, failed: 0, elapsed: 00:00:03.8370598 queued: 6000/20000, success: 5800, failed: 0, elapsed: 00:00:04.6621606 queued: 7000/20000, success: 6800, failed: 0, elapsed: 00:00:05.4589104 queued: 8000/20000, success: 7800, failed: 0, elapsed: 00:00:06.2913588 queued: 9000/20000, success: 8800, failed: 0, elapsed: 00:00:07.0629536 queued: 10000/20000, success: 9800, failed: 0, elapsed: 00:00:07.8438472 queued: 11000/20000, success: 10800, failed: 0, elapsed: 00:00:08.5796209 queued: 12000/20000, success: 11800, failed: 0, elapsed: 00:00:09.3663975 queued: 13000/20000, success: 12801, failed: 0, elapsed: 00:00:10.1984757 queued: 14000/20000, success: 13800, failed: 0, elapsed: 00:00:11.0474925 queued: 15000/20000, success: 14800, failed: 0, elapsed: 00:00:11.9175753 queued: 16000/20000, success: 15800, failed: 0, elapsed: 00:00:12.7356429 queued: 17000/20000, success: 16801, failed: 0, elapsed: 00:00:13.4991148 queued: 18000/20000, success: 17800, failed: 0, elapsed: 00:00:14.2912941 queued: 19000/20000, success: 18800, failed: 0, elapsed: 00:00:15.0844828 queued: 20000/20000, success: 19800, failed: 0, elapsed: 00:00:15.8439387 done: success20000, failed0, elapsed00:00:15.9485251局限与备注别把结论用错地方客户端与服务器同机TIME_WAIT 统计包含两端连接不能完全归因于“客户端端口耗尽”但它足以说明“短时间制造大量短连接”这件事本身的风险。net48 设置了ServicePointManager.DefaultConnectionLimit 1000与 net6/net10 的连接管理策略存在差异。关键结果汇总TIME_WAIT 统计端口 5055运行before TIME_WAITafter TIME_WAIT耗时秒net4822000217.754net602000018.018net801836116.427net1001886017.400net10-static020015.851net10-factory20020015.949来源logs/run-20260119-095017/netstat.log客户端执行结果摘要net48: success20000, failed0net6: success20000, failed0net8: success18361, failed1639报错“通常每个套接字地址只允许使用一次”net10-new: success18860, failed1140报错“通常每个套接字地址只允许使用一次”net10-static: success20000, failed0net10-factory: success20000, failed0来源logs/run-20260119-095017/*.out.log结论“.NET 10 了HttpClient 还能不能 using”——答案依然是别把 HttpClient 当成一次性对象。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2476470.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!