Dapper的QueryAsync在高并发下变慢主因是误用伪异步、连接池瓶颈及调用链未全异步,非Dapper本身问题;需确保驱动原生异步、连接池配置合理、全程async/await且避免同步阻塞。

为什么 Dapper 的 QueryAsync 在高并发下有时比同步还慢
不是 Dapper 本身有问题,而是常见误用导致异步收益被抵消。典型场景是:在 ASP.NET Core 中用 Task.Run(() => connection.Query(...)) 包裹同步方法假装“异步”,这反而增加线程调度开销,吞吐不升反降。
真正有效的异步必须依赖底层驱动的 I/O 异步能力(如 SQL Server 的 SqlConnection 对 SqlClient 的原生支持),否则只是“伪异步”。
-
QueryAsync和ExecuteAsync必须配合await使用,不能丢弃返回的Task - 确保连接字符串含
Asynchronous Processing=true(.NET Framework)或使用Microsoft.Data.SqlClient(.NET Core/5+ 默认启用) - 避免在异步方法中调用
.Result或.Wait()—— 这会阻塞线程池线程,高并发时迅速耗尽
Dapper 异步查询必须搭配 async/await 链路全异步
从 HTTP 入口到数据库操作,中间任何一环同步阻塞都会让异步失效。比如 Controller 方法声明为 async Task,但内部调用了某个同步封装的仓储方法,整个请求仍会占用一个线程直到完成。
常见断点位置:日志记录、缓存读写(IDistributedCache.GetAsync)、DTO 映射(若含同步计算逻辑)。
- 检查所有
await调用是否真异步 —— 比如MemoryCache的GetOrCreateAsync是真异步,但GetOrCreate是同步的 - 避免在
using var conn = new SqlConnection(...)块内做耗时 CPU 操作(如大列表Select投影),应先await conn.QueryAsync拿到数据再处理() - 批量查询慎用
QueryMultipleAsync:它虽支持多结果集,但内部仍是单连接顺序读取,高并发下易成瓶颈;可考虑拆成并行的独立QueryAsync(注意连接数限制)
连接池与并发数不匹配是性能拐点的主因
Dapper 本身无连接管理,完全依赖 SqlConnection 的连接池。默认最大连接数是 100,当并发请求数持续超过该值,后续请求会在连接池队列中等待,表现为 System.Data.SqlClient.SqlException: Timeout expired 或高延迟。
1、对ASP内核代码进行DLL封装,从而大大提高了用户的访问速度和安全性;2、采用后台生成HTML网页的格式,使程序访问速度得到进一步的提升;3、用户可发展下级会员并在下级购买商品时获得差额利润;4、全新模板选择功能;5、后台增加磁盘绑定功能;6、后台增加库存查询功能;7、后台增加财务统计功能;8、后台面值类型批量设定;9、后台财务曲线报表显示;10、完善订单功能;11、对所有传输的字符串进行安全
这不是 Dapper 的锅,但容易误判为“Dapper 不行”。真实瓶颈在连接资源,而非 ORM 层。
- 监控
SqlServer:Connection Pool\Number of current connections性能计数器(Windows)或应用日志中的连接等待时间 - 必要时调整连接字符串:
Max Pool Size=200;,但需同步评估 SQL Server 的 max worker threads 是否足够 - 避免长期持有连接:不要把
SqlConnection提升为类字段或单例,每次查询都新建 +using释放
public class UserRepository
{
private readonly string _connectionString;
public UserRepository(string connectionString) => _connectionString = connectionString;
public async TaskzuojiankuohaophpcnUseryoujiankuohaophpcn GetByIdAsync(int id)
{
// ✅ 正确:短生命周期连接,真异步 I/O
await using var conn = new SqlConnection(_connectionString);
return await conn.QueryFirstOrDefaultAsynczuojiankuohaophpcnUseryoujiankuohaophpcn(
"SELECT * FROM Users WHERE Id = @id",
new { id });
}}
高并发下最常被忽略的,是以为换用 QueryAsync 就万事大吉,却没验证连接池是否撑得住、调用链是否真异步、驱动是否启用原生异步。这些点卡住一个,性能就上不去。










