NET 中 Async/Await 的演进:从状态机到运行时优化的 Continuation

news/2025/9/18 4:39:30/文章来源:https://www.cnblogs.com/ProjectDD/p/19097964

NET 中 Async/Await 的演进:从状态机到运行时优化的 Continuation

 

C# 的 `async/await` 长期以来是编写简洁、非阻塞代码的基石,但其传统实现——每个异步方法生成一个独立状态机——在高性能场景(如递归或链式异步调用)中暴露出显著局限性。2025 年的 .NET 9 和 .NET 10 引入了革命性方案:运行时动态管理的异步处理(runtime-handled async)。本文基于近期技术讨论,精炼梳理传统模型的缺陷、新方案的核心,以及其对性能和开发的深远影响。

## 传统 Async/Await 的缺陷

C# 5.0(2012)引入的 `async/await` 让异步代码如同步般直观,但其编译器驱动的设计存在明显问题:

- **每个方法一个状态机**:Roslyn 编译器将每个 `async` 方法转为状态机结构体(`IAsyncStateMachine`),用 `switch` 跟踪 await 点。例如,递归方法 `async Task<long> FibAsync(int n)` 有两个 await(`n-1` 和 `n-2`),每次调用生成新状态机和 `Task` 对象。若 `n=30`,指数级调用(约 2^n)导致数百万分配,GC 压力巨大。
- **内存与 GC 开销**:每个状态机和 `Task`(约 100-200 字节)都在堆上分配,状态机装箱(boxing)进一步增加成本。长链或递归场景下,内存使用和 GC 暂停使性能下降 20-50%(如高吞吐 Web API)。
- **协调与调试复杂**:多状态机通过 `Task` 的 Continuation 协调,链长或递归时回调嵌套导致延迟(增加 10-20%)和调试困难(栈碎片化)。
- **动态场景瓶颈**:如 `FibAsync`,递归展开的 await 点无法在编译时预测,静态生成的状态机无法优化,分配爆炸。

尽管功能上“能跑通”,但性能缺陷明显,尤其在高性能场景下。

## 新方案:运行时动态管理异步

.NET 9 和 .NET 10(2025 年 RC1)通过 runtime-handled async(或 AsyncHelpers)彻底革新了异步模型,解决了传统缺陷:

- **编译时仅标注**:编译器不再为每个 `async` 方法生成完整状态机,仅标记 await 点、局部变量和 Continuation 位置,生成轻量 IL 代码。这简化了编译输出,移交动态逻辑给运行时。
- **运行时动态管理**:JIT 或 CLR 在运行时根据标注动态构建 Continuation 链,隐式管理状态(类似单一状态机效果)。这通过 JIT 优化(如内联、PGO)或 VM 层实现,减少状态机实例和 `Task` 分配(从 O(n) 到 O(1) 或 0)。
- **ValueTask 集成**:运行时广泛使用 `ValueTask`(值类型,栈优先)作为 Continuation 载体,同步场景零分配,异步时共享轻量源(如 `IValueTaskSource`),大幅减少 GC 压力。
- **线性 Continuation 链**:运行时将异步链抽象为“线性节点序列”(类似 continue 标签),每个 await 点像入栈/出栈操作,等待和恢复顺序与代码呈现一致,简化协调并避免传统嵌套回调的复杂性。

以 `FibAsync` 为例:
```csharp
async ValueTask<long> FibAsync(int n) {
if (n <= 1) return n;
return await FibAsync(n - 1) + await FibAsync(n - 2);
}
```
传统模型为每次递归生成状态机和 `Task`,指数级分配;新方案中,运行时动态融合 Continuation,减少 30-50% 内存,延迟降低 10-20%。

## 异步调用链的线性与并发

异步调用链(如 `await MethodA() -> await MethodB()`)在时间和逻辑上是线性的,await 点的顺序与代码呈现一致,运行时通过动态 Continuation 链强化这一特性,确保直观性和可预测性。 同时,.NET 支持并发:
- **并发能力**:通过 `Task.WhenAll` 或 `Task.Run`,多个异步链可并行运行,利用多核处理器。例如:
```csharp
async Task Run() => await Task.WhenAll(Chain1(), Chain2(), Chain3());
```
每个链内线性,链间并行,运行时优化调度(.NET 10 改进 ThreadPool 工作窃取),提升吞吐量 ~15%。
- **根节点识别**:每个 `async` 方法是链的根节点,运行时从根方法(如 `Chain1()`)开始动态解析 Continuation,管理整个链。开发者只需指明根,运行时处理复杂逻辑。

## 其他优化细节

新模型的性能提升不仅来自运行时管理,还包括:
- **移除 Boxing**:.NET 9 优化 `AwaitUnsafeOnCompleted`,减少状态机装箱,降低 GC 开销。
- **JIT 与 PGO**:动态优化 Continuation 链,内联和循环展开提升递归场景性能(如 `FibAsync`)。
- **GC 改进**:.NET 10 的动态阈值 GC 缓解高分配场景的暂停问题。

## 总结与展望

从编译时状态机到运行时动态管理的转变,.NET 9/10 解决了传统 `async/await` 的核心缺陷:高内存分配、协调复杂和动态场景瓶颈。异步调用链的线性本质和并发支持(通过 `Task.WhenAll`)在运行时优化下更加高效,`ValueTask` 和 JIT 技术进一步减少开销。未来,.NET 10 或更高版本可能完全取代传统模型,提供更无缝的异步体验。

**实践建议**:
- 使用 `async ValueTask` 重写高频或递归方法,测试性能提升。
- 用 BenchmarkDotNet 对比 .NET 8 和 10 的异步性能。
- 关注 GitHub dotnet/runtime(如 #94620)获取最新 AsyncHelpers 进展。

.NET 的异步编程正迈向更高效、直观的未来!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/906974.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 Ansible 管理服务器集群

Inventory Ansible 使用 /etc/ansible/hosts 管理受控服务器列表: --- ungrouped:hosts:node-1:ansible_host: 192.168.1.1ansible_user: johnnode-2:ansible_host: 192.168.1.2ansible_user: janenode-3:ansible_hos…

1现在处于非常破防的阶段,不知道为什么会打成这个样子。 ABC 过得很快。看到 D1 的第一眼就会了,发现转移只需要随便优化一下就能通过 D2,不太想写。E 看上去挺可做,F 看上去是板子题。于是开始写 F,不知道这种代…

US$109 NEC CHIP Smart Remote Key Fob For Benz C E Class (2 Batteries) 433Mhz 10pcs/lot

NEC CHIP Smart Remote Key Fob For Benz C E Class (2 Batteries) 433Mhz 10pcs/lot Package includes:10 pc x NEC CHIP Smart Remote Key Fob For Benz C E Class (2 Batteries) 433Mhz Pictures of NEC CHIP Smart…

Codeforces Round 1051 (Div. 2)

A. All Lengths Subtraction 题意:一个排列,对于每个\(k \in [1, n]\),你都要选择一个长度为\(k\)的子数组使得它们都减一,求有没有方案使得最终所有数都是\(0\)。 考虑\(k\)从大到小,发现做\(n\)的时候\(1\)变成…

US$11 3 Button Flip Folding Remote Key Fob with ID46 Chip 433 MHZ For Hyundai i30 ix35

3 Button Flip Folding Remote Key Fob with ID46 Chip 433 MHZ For Hyundai i30 ix35Package List:1pc x 3 Button Flip Folding Remote Key Fob with ID46 Chip 433 MHZ For Hyundai i30 ix35 Pictures of 3 Button …

US$39.99 3+1 Button Remote Key for Nissan 315Mhz FCC ID KBRASTU15 10pcs/lot

3+1 Button Remote Key for Nissan 315Mhz FCC ID KBRASTU15 10pcs/lotPackage includes:10pc x 3+1 Button Remote Key for Nissan 315Mhz FCC ID KBRASTU15 Pictures of 3+1 Button Remote Key for Nissan 315Mhz FC…

再不学就晚了!RDT LeRobot与RDKS100部署详解

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 机械臂:LeRobot-SO101 数采机:MacBook-Pro Python3.10 开发机:Ubuntu 22.04, Cuda12.4,8 NVIDIA A100-SXM4-40GB 开发板:RDK OS 4.0.2 Bas…

编译Unity4.3.1f1

参考: 编译 Unity 4.3.1 引擎_unity-source-4.3.1f1-CSDN博客 Unity 4.3.1f1编译调试 - 知乎 Unity source 4.3.1f1 源代码分析-腾讯游戏学堂 附: 早期版本下载(4.x之前的版本)

[.NET逆向] Listary

View Post[.NET逆向] Listary[.NET逆向] Listary v6.3.5.94 前段时间在吾爱论坛闲逛,偶遇一篇帖子,自己便动手实操了一番 原文链接:https://www.52pojie.cn/thread-2025340-1-1.html I.工欲善其事必先利其器 a.List…

US$19 Smart Key Fob For Nissan Micra/Juke/Note Renault Alaska 433MHz

Smart Key Fob For Nissan Micra/Juke/Note Renault Alaska 433MHzPackage includes:1pc x Smart Key Fob For Nissan Micra/Juke/Note Renault Alaska 433MHz Pictures of Smart Key Fob For Nissan Micra/Juke/Note …

py -m pip show workalendar

py -m pip show workalendarpy -m pip show workalendar

【R课堂-电机专栏】为什么提高电机的电压时,转速会随之上升?

本文探讨的问题是 “为什么提高电机的电压时,转速会随之上升?”具体而言,就是当给电机绕组施加的电压升高(增大)时,为什么其转速会随之上升。这一现象看似理所当然,但其背后的原理却涉及诸多物理公式。这个问题…

抽象 CF

一道题在 CF 上有三倍经验,我有个细节假了: \(n \le 10^5\),84 个点的那道在 #64 寄了。 \(n \le 2 \times 10^5\),88 个点的那道在 #88 寄了。 \(n \le 5 \times 10^5\),111 个点的那道直接 A 了。

Day 007 顺序结构与选择结构-Java流程控制

Day 007 顺序结构与选择结构-Java流程控制$(".postTitle2").removeClass("postTitle2").addClass("singleposttitle");Java流程控制 顺序结构java的基本结构就是顺序结构,除非特别指明…

US$29 5 Button Smart key for Cadillac QN-RF629X 315MHZ/433MHZ FCC ID: HYQ2AB

5 Button Smart key for Cadillac QN-RF629X 315MHZ/433MHZ FCC ID: HYQ2AB Package includes:1pc x 5 Button Smart key for Cadillac QN-RF629X 315MHZ/433MHZ FCC ID: HYQ2AB Pictures of 5 Button Smart key for C…

单元测试之Mockito使用

测试中为什么需要Mock 在实际的测试中,被测试的对象并不都是可以通过简单的new操作符就可以创建出来的! 实际的业务代码中,一个业务类往往要依赖很多其他的类才能完成一个完整的业务方法,这些依赖包括第三方的rpc,…

Jetson有Jtop,Linux有Htop,RDK也有Dtop!

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 本项目基于btop开源项目进行二次开发,旨在为RDK平台提供更强大的系统监控工具。 Linux系统下有Htop可以作为系统监控,英伟达的Jetson也有第三方的…

《原子习惯》-读书笔记4

2025.09.17 Day4 1、 养成习惯的过程可以分为四个简单的步骤:提示、渴求、反应和奖励。2、你的头脑在不断分析你的内外部环境,寻找奖励所在的线索。因为线索是我们已然接近奖励的第一个迹象,它自然会导致人们滋生渴…

Maven的配置

Maven的配置配置Maven 下载并配置Maven文件 1.[官网](Welcome to Apache Maven – Maven)下载Maven2.下载完毕后解压到文件夹中。3.配置环境变量系统环境变量名 变量值新建 MAVEN_HOME maven所在目录新建 M2_HOME mave…

JavaWeb基础知识1

JavaWeb基础知识1JavaWeb 1.基本概念 web开发:web,网页的意思 静态webhtml,css 提供的数据始终不会变化动态web提供的信息会改变 技术栈:Servlet/JSP ,ASP ,PHP在Java中,动态web资源开发的技术统称JavaWeb 1.2web应…