基于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 无收益
相关推荐
迷枫71211 分钟前
SQL性能排查记录
java·数据库·sql
Elastic 中国社区官方博客7 小时前
搜索倍增器:推动收入、生产力和 AI 实现规模化
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
保定公民9 小时前
达梦数据库存储过程中的数组类型详解:基础数组与记录数组的差异化应用
数据库·达梦·存储过程·达梦数据库·dm8·dm
梦Arrebol10 小时前
Redis 内容及相关实验
数据库·redis
大模型码小白10 小时前
Spring AI Tool 实现自然语言操作 MySQL 数据库详解
服务器·开发语言·数据库·人工智能·python·mysql·spring
Behaviour10 小时前
Unity UI循环列表UIScrollViewContent实现
ui·unity·c#·游戏引擎
c#上位机11 小时前
C#上位机项目实战——C#的dll项目编译时拷贝到指定目录下
开发语言·c#
曹牧11 小时前
C#:数组与列表的差异
开发语言·c#
DBA大董12 小时前
TDengine3.0 DBA常用的运维命令和SQL2
运维·数据库·时序数据库·dba·tdengine