0

0

c# TestServer 在ASP.NET Core并发测试中的应用

星降

星降

发布时间:2025-12-31 09:41:26

|

353人浏览过

|

来源于php中文网

原创

TestServer本身不支持并发请求,必须复用同一HttpClient实例发起并发调用;其瓶颈在中间件和DI容器,而非网络,适用于功能与集成验证,非压测工具。

c# testserver 在asp.net core并发测试中的应用

TestServer 本身不支持并发请求,必须配合 HttpClient 实例复用

ASP.NET Core 的 TestServer 是一个内存内服务器,它运行在当前进程,没有网络层开销。但它内部的 IServer 实现(TestServer)是单线程同步处理请求的——不是线程安全的,也不自动排队或并行化请求。直接在多线程中反复调用 server.CreateClient() 并发发请求,容易触发 ObjectDisposedException 或请求挂起。

正确做法是:创建一个 TestServer 实例,**复用同一个 HttpClient 实例**(由 TestServer.CreateClient() 返回),再通过该客户端发起并发请求。这个 HttpClient 内部会复用连接、支持 HTTP/1.1 管道化(虽默认禁用)和 HTTP/2 多路复用(取决于底层 SocketsHttpHandler 配置)。

  • TestServer 实例应全局生命周期(如 xUnit 的 IClassFixture),避免重复构建中间件管道
  • 每个测试方法里不要反复调用 CreateClient();若需不同配置(如带 token 的 client),可用 new HttpClient(handler) { BaseAddress = ... } 复用底层 HttpMessageHandler
  • 并发请求数量不宜超过 ServicePointManager.DefaultConnectionLimit(.NET 5+ 默认为 int.MaxValue,但旧版默认 2)

并发测试时必须手动 await 所有 Task,不能只用 Task.Run + Wait()

常见错误是用 Task.Run(() => client.GetAsync("/api/values")).Wait() 混合同步阻塞和异步逻辑,极易引发死锁(尤其在 xUnit 默认无 SynchronizationContext 的上下文中反而少见,但在某些集成测试宿主里仍可能)。

真正并发要靠 Task.WhenAllParallel.ForEachAsync(.NET 6+)驱动异步任务集合:

var tasks = Enumerable.Range(0, 100)
    .Select(_ => client.GetAsync("/api/values"))
    .ToArray();
await Task.WhenAll(tasks); // ✅ 正确:全部并发发起,统一等待完成
  • 别用 Parallel.For 直接调用 async 方法——它不理解 async/await,会导致返回 void 任务丢失
  • 若需控制并发度(比如限制同时最多 10 个请求),用 SemaphoreSlim 包裹请求逻辑,而不是依赖线程池
  • 注意 HttpClient 的 DNS 缓存和连接复用行为:短时间高频请求下,连接不会立刻断开,实际压力更接近真实服务端负载

TestServer 并发瓶颈不在网络,而在中间件和依赖注入容器

因为 TestServer 完全绕过 Socket、TLS、Kestrel 请求队列等环节,真正的性能瓶颈往往出在你自己的代码里:

DVWA
DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中存在已记录和未记录的漏洞。这是有意的。鼓励您尝试发现尽可能多的问题。Damn Vulnerable Web A

下载
  • 控制器中用了 Task.Run(...).Result.Wait() —— 会阻塞线程池线程,快速耗尽 ThreadPool.GetAvailableThreads()
  • 注册了 Scoped 服务但未在请求范围内正确释放(比如 EF Core 的 DbContext 被意外提升为 Singleton)
  • 使用了非线程安全的静态缓存(如 static Dictionary)且未加锁
  • 日志组件(如 Serilog 的 ConsoleSink)在高并发下成为 I/O 瓶颈

验证方式:把被测服务换成空 app.Use((ctx, next) => next());,再压测。如果此时并发吞吐突增,说明瓶颈确实在业务中间件中。

替换 TestServer 前,先确认你真需要“并发测试”而非“负载模拟”

TestServer 的定位是**功能与集成验证**,不是压测工具。它无法反映真实网络延迟、TLS 握手开销、反向代理行为、连接中断重试等场景。如果你发现:

  • 并发 100 请求就超时,但生产环境 Kestrel 能扛 5000+ QPS
  • 测试结果与 curl -s -w "\n%{http_code}\n" http://localhost:5000/api/test 差距巨大
  • 想测熔断、限流、降级策略(这些通常在网关或基础设施层)

那就该换方案了:用 dotnet run 启动真实 Kestrel,再用 bombardierheyArtillery 发压。或者,在 CI 中部署临时容器跑真实服务 + HttpClient 远程调用。

TestServer 的并发测试,只适合回答一个问题:“我的 Controller 和 Service 在多个请求同时进入时,会不会状态错乱、抛异常、漏 Dispose?”——它不是性能报告生成器。

相关专题

更多
什么是中间件
什么是中间件

中间件是一种软件组件,充当不兼容组件之间的桥梁,提供额外服务,例如集成异构系统、提供常用服务、提高应用程序性能,以及简化应用程序开发。想了解更多中间件的相关内容,可以阅读本专题下面的文章。

175

2024.05.11

Golang 中间件开发与微服务架构
Golang 中间件开发与微服务架构

本专题系统讲解 Golang 在微服务架构中的中间件开发,包括日志处理、限流与熔断、认证与授权、服务监控、API 网关设计等常见中间件功能的实现。通过实战项目,帮助开发者理解如何使用 Go 编写高效、可扩展的中间件组件,并在微服务环境中进行灵活部署与管理。

212

2025.12.18

curl_exec
curl_exec

curl_exec函数是PHP cURL函数列表中的一种,它的功能是执行一个cURL会话。给大家总结了一下php curl_exec函数的一些用法实例,这个函数应该在初始化一个cURL会话并且全部的选项都被设置后被调用。他的返回值成功时返回TRUE, 或者在失败时返回FALSE。

422

2023.06.14

linux常见下载安装工具
linux常见下载安装工具

linux常见下载安装工具有APT、YUM、DNF、Snapcraft、Flatpak、AppImage、Wget、Curl等。想了解更多linux常见下载安装工具相关内容,可以阅读本专题下面的文章。

172

2023.10.30

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6039

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

781

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1044

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

1085

2024.03.01

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

相关下载

更多

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 39.7万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号