0

0

c# 如何在循环中正确使用 async await

畫卷琴夢

畫卷琴夢

发布时间:2026-01-10 08:52:02

|

697人浏览过

|

来源于php中文网

原创

for循环中直接await变慢是因为异步操作被强制串行执行,总耗时≈各请求耗时之和;应改用Task.WhenAll并发执行,避免闭包陷阱和编译错误。

c# 如何在循环中正确使用 async await

为什么在 for 循环里直接 await 会变慢

因为 await 默认是顺序等待:前一个异步操作没完成,后一个根本不会发起。比如调用 10 次 HttpClient.GetAsync(),实际是串行发请求,总耗时 ≈ 所有请求耗时之和。

这不是 await 本身的问题,而是写法让它“不敢并发”。关键在控制权交还时机和任务调度逻辑。

如何让多个 async 调用真正并发执行

把异步操作包装成 Task,先全部启动,再统一 await Task.WhenAll(...) 等待全部完成。

  • ✅ 正确做法:用
    var tasks = urls.Select(url => client.GetAsync(url)).ToArray(); await Task.WhenAll(tasks);
  • ❌ 错误写法:for (int i = 0; i < urls.Length; i++) { await client.GetAsync(urls[i]); } —— 完全串行
  • ⚠️ 注意:Task.WhenAll 不会改变异常行为 —— 任一任务失败,整个 await 就抛出 AggregateException,需用 try/catch 或检查 task.Exception
  • ⚠️ 内存与连接数:并发太多可能触发 HttpClient 连接池限制或服务器限流,建议配合 SemaphoreSlim 限流

需要按顺序处理结果时怎么写

Task.WhenAll 返回的 Task 结果数组,下标和原始输入顺序严格一致。不需要额外排序或映射。

AI小聚
AI小聚

一站式多功能AIGC创作平台,支持AI绘画、AI视频、AI聊天、AI音乐

下载
var tasks = ids.Select(async id => {
    var res = await client.GetAsync($"/api/item/{id}");
    return await res.Content.ReadFromJsonAsync();
});
var results = await Task.WhenAll(tasks); // results[0] 对应 ids[0] 的结果

如果中间某次请求失败,对应位置的 results[i] 会是 null(除非你显式 throw),但更稳妥的是用 Task.WhenAll + 单独 try/catch 包裹每个 lambda。

foreach 里用 async lambda 为什么编译不过

因为 async voidasync Funcforeach 中容易捕获错误的变量(闭包陷阱),且编译器不支持直接在 foreach 语句块中写 await(会报 CS1992 “无法在匿名方法、lambda 表达式或查询表达式中使用 await”)。

  • ✅ 解决:改用 Select + async lambda,或提前把循环变量复制到局部变量(如 var current = item;
  • ✅ 更安全写法:foreach (var item in list) { var t = ProcessAsync(item); tasks.Add(t); },然后 await Task.WhenAll(tasks)
  • ⚠️ 切勿写:foreach (var item in list) { await ProcessAsync(item); } —— 又回到串行
真正难的不是语法,是判断哪些操作必须等、哪些可以放一起跑,以及失败后要不要重试、要不要记录中间状态。这些没法靠 await 自动解决。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

231

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

435

2024.03.01

php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

41

2025.12.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

315

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

533

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

51

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

193

2025.08.29

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2023.11.23

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

25

2026.01.09

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.2万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.1万人学习

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

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