基于C#的ASP.NET Core中分析async、await的使用场景

文章速览

一个赞,留下专属于你的足迹!

一、何时使用async/await

1.核心判断标准

场景 是否使用 async 原因
I/O 操作(数据库、文件、网络请求) ✅ 必须用 释放线程,提高并发
CPU 密集型计算 ❌ 不需要 应该使用 Task.Run 或直接同步
纯内存操作 ❌ 不需要 增加复杂度,无性能收益

2.示例代码

csharp 复制代码
// ✅ 数据库查询 - 需要 async
public async Task<string> GetAllBigClassAsync()
{
    var list = await _context.BigClasses.ToListAsync();  // I/O 操作
    return JsonSerializer.Serialize(list);
}

// ✅ 数据库保存 - 需要 async  
public async Task<string> DeleteNumberDataAsync(int dataId, int userId)
{
    var user = await _context.Users.FindAsync(userId);   // I/O 操作
    // ... 修改数据
    await _context.SaveChangesAsync();                    // I/O 操作
}

二、深度分析:为什么在此类场景中频繁出现?

1.web应用的线程池机制

在ASP.NET Core中,线程池是有限的,大约1000个线程。假设不用async:

csharp 复制代码
// ❌ 同步版本(阻塞线程)
public string GetAllBigClassSync()
{
    var list = _context.BigClasses.ToList(); // 线程被卡住,等待数据库返回
    return JsonSerializer.Serialize(list);
}

出现的问题是:当1000个用户同时请求时,线程池耗尽,第1001个用户必须等待。

使用async后:

  • 发出数据库请求后,当前线程立刻释放,可以处理其他用户请求
  • 数据库返回数据后,从线程池取一个空闲线程继续执行
  • 并发能力提升10-100倍

2.Entity Framework Core的设计

EF Core从底层支持异步,所有的I/O方法都有Async后缀:

csharp 复制代码
// 在你的代码中出现的 EF Core 异步方法:
await _context.BigClasses.ToListAsync();
await _context.NumberRecords.FindAsync(dataId);
await _context.SaveChangesAsync();
await _context.NumberRecords
    .Where(d => d.DataState == 1)
    .CountAsync();
await _context.Database.BeginTransactionAsync();

关键点:数据库查询是网络I/O,不是CPU计算,也正是async的最佳场景。

三、同步vs异步对比分析

1.代码对比

维度 同步方法 异步方法(你的代码)
方法签名 string GetData() async Task<string> GetDataAsync()
数据库查询 .ToList() await .ToListAsync()
线程行为 阻塞线程,干等 释放线程,回调继续
并发能力 低(线程池耗尽) 高(支撑万级并发)
代码复杂度 简单直接 需要 async/await 链

2.执行流程对比

假设一个请求需要查询数据库(耗时100ms):

同步版本:

时间点: 线程1状态

0ms 开始执行->发送sql->阻塞等待

100ms 收到结果->返回Json

期间线程1被完全占用,无法处理其他请求

异步版本:

时间点: 线程1状态 线程2状态

0ms 开始执行->发送sql->立刻释放 处理其他请求

100ms 空闲 收到结果->继续执行->返回Josn

总结

项目类型 推荐做法 原因
Web API / Razor Pages 全面使用 async I/O 密集,并发要求高
后台定时任务 可部分使用同步 单线程执行,无需高并发
WinForm/WPF async + ConfigureAwait(false) 避免 UI 线程死锁
计算密集型(图像处理、大数据计算) 同步或 Task.Run 不是 I/O,async 无收益
相关推荐
心中有你021421 分钟前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
龙亘川36 分钟前
综合素质评价业务建模:从过程性评价到成长档案全链路闭环
数据库·智慧城市·数据可视化
数据库小组41 分钟前
NineData 实战教程:MySQL 5.5 数据迁移同步到 MySQL 8.0(跨版本升级)
数据库·mysql·mysql优化·数据库开发·数据库迁移·版本升级·数据复制
zhangjw341 小时前
1-5 PostgreSQL 数据类型全集:基础类型、字符串、数值、时间类型
数据库·postgresql
王中阳Go2 小时前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型
cnskylee2 小时前
【MySQL】麒麟V10 SP3系统安装MySQL-Commercial-8.0.46
数据库·mysql·adb
梦幻通灵2 小时前
修改MySQL数据库递增序列【持续更新】
数据库·mysql
liminla!2 小时前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法
tongyiixiaohuang2 小时前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
caimouse3 小时前
MonoDevelop 编译用户应用程序时调用的是哪个编译器
c#