0

0

C# async/await的底层原理是什么 - 深入解析状态机与线程上下文

月夜之吻

月夜之吻

发布时间:2025-12-04 12:56:02

|

180人浏览过

|

来源于php中文网

原创

async/await基于编译器生成的状态机实现,每次await暂停会保存执行状态,恢复时从中断点继续;其核心是编译器将异步方法转换为实现iasyncstatemachine的结构体,通过movenext()驱动流程。await操作依赖awaiter对象的iscompleted、oncompleted和getresult三个成员,判断是否同步完成或注册回调以异步恢复。执行上下文由synchronizationcontext或taskscheduler决定,ui线程中会自动捕获上下文确保回到原线程,而configureawait(false)可禁用此行为以提升性能并避免死锁。async/await不创建新线程,挂起期间线程返回线程池,恢复时由调度器安排续体执行,利用底层i/o或任务调度实现并发,无栈撕裂与线程阻塞,高效支持异步编程。

c# async/await的底层原理是什么 - 深入解析状态机与线程上下文

async/await 不是语法糖,而是编译器驱动的状态机

当你写 async Task GetDataAsync(),C# 编译器不会生成普通方法,而是将其重写为一个**状态机结构体(struct)**,实现 IAsyncStateMachine 接口。这个结构体包含:字段(保存局部变量、参数、awaitable 对象)、MoveNext() 方法(核心执行逻辑)、State 字段(记录当前执行到哪一步)。每次 await 暂停时,不是线程被阻塞,而是状态机被“冻结”并保存现场;恢复时,从上次 State 值继续执行 MoveNext()。

await 的本质是“可等待对象”的约定调用

await 后的对象必须实现 GetAwaiter() 方法,返回一个具备以下成员的 awaiter:

  • IsCompleted:同步完成?若为 true,直接取 Result,不挂起
  • OnCompleted(Action):注册回调,当异步操作完成时被调用
  • GetResult():获取结果或抛出异常(可能含副作用,如释放资源)

常见 awaitable 类型如 Task、Task、ValueTask、自定义 awaiter 都遵循该模式。编译器在 await 处插入逻辑:检查 IsCompleted → 若否,调用 OnCompleted 注册续体(continuation),然后 return;若是,跳过挂起直接执行后续代码。

同步上下文(SynchronizationContext)决定 await 后在哪执行

await 恢复执行的位置,不取决于“谁调用了它”,而取决于当前捕获的 SynchronizationContextTaskScheduler

Dora
Dora

创建令人惊叹的3D动画网站,无需编写一行代码。

下载
  • UI 线程(WinForms/WPF):自动捕获 UI 上下文,await 后回到原 UI 线程(避免跨线程访问控件异常)
  • ASP.NET(旧版):捕获 HttpContext 关联的上下文,确保 Request/Response 可用
  • 控制台/默认线程池:无上下文,await 后由任意线程池线程执行(无序、不可预测)

可用 ConfigureAwait(false) 显式禁用上下文捕获,提升性能并避免死锁(尤其在库代码中强烈推荐)。

线程本身不被“切换”,但执行流被调度器接管

async/await 不创建新线程,也不强制线程切换。真正的并发来自底层 I/O(如 FileStream.ReadAsync)或任务调度(如 Task.Run)。await 挂起后,线程通常回归线程池处理其他请求;恢复时,由调度器将续体排入目标上下文(如 UI 消息队列)或线程池队列。整个过程无撕裂、无线程阻塞——这是它高效的关键。

基本上就这些。理解状态机构造、awaiter 协议和上下文流转,就能看透 async/await 的行为边界与性能特征。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

string转int
string转int

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

1010

2023.08.02

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

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

611

2024.08.29

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

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

334

2025.08.29

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

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

235

2025.08.29

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1923

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

656

2025.10.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

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

精品课程

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

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