C#中async await异步关键字用法和异步的底层原理

目录

  • C#异步编程
    • 一、异步编程基础
    • 二、异步方法的工作原理
    • 三、代码示例
    • 四、编译后的底层实现
    • 五、总结

C#异步编程

一、异步编程基础

  1. 异步编程是啥玩意儿
    • 就是让程序在干等着某些耗时操作(比如等网络响应、读写文件啥的)的时候,能把线程腾出来干别的活儿,这样程序就能更灵敏、更高效啦。
    • 跟同步编程不一样,同步编程就是老老实实等着操作完成才继续往下走,线程就一直被占着,多浪费啊。
  2. 异步编程的好处
    • 响应快:比如在做UI界面的时候,用了异步编程,界面就不会卡啦,用户体验贼棒。
    • 省资源:不用让线程一直干等着,资源利用率就上去了。
    • 能扛更多活儿:面对一大堆并发操作的时候,异步编程能轻松搞定,扩展性杠杠滴。

二、异步方法的工作原理

  1. 异步方法咋被编译的
    • 你写个async修饰的方法,编译器就把它变成一个状态机啦。
    • 状态机会根据await表达式把方法拆成好多个状态,就跟玩拼图一样。
  2. 状态机是咋干活的
    • 状态机就是编译器生成的一个类,它得记着异步方法执行到哪儿了。
    • 核心就是MoveNext方法,它就像导演一样,指挥着异步操作一步步往下走。
    • 每碰到一个await,就切换一下状态。
  3. await底层是咋实现的
    • await就整出个等待器(awaiter),专门等着异步操作完成。
    • 要是操作还没完,await就记下当前状态,等操作完了再继续往下走。

三、代码示例

  1. HttpClient干异步网络请求
    • 弄个HttpClient对象,用来发HTTP请求。
    • GetStringAsync方法,就能异步拿到指定URL的网页内容啦。
    • 把拿到的内容打印出来,瞧一瞧成果。
using System;
using System.Net.Http;
using System.Threading.Tasks;namespace asyncawait原理1
{class Program{static async Task Main(string[] args){using (HttpClient httpClient = new HttpClient()){string html = await httpClient.GetStringAsync("https://www.baidu.com");Console.WriteLine(html);}}}
}
  1. 异步读写文件
    • File.WriteAllTextAsync方法,能把文本异步写到指定路径的文件里。
    • File.ReadAllTextAsync方法,就能把文件内容异步读出来。
    • 把读到的内容打印出来,看看对不对。
using System;
using System.IO;
using System.Threading.Tasks;namespace asyncawait原理1
{class Program{static async Task Main(string[] args){string txt = "hello world";string filename = @"E:\temp\1.txt";await File.WriteAllTextAsync(filename, txt);Console.WriteLine("写入成功");string s = await File.ReadAllTextAsync(filename);Console.WriteLine("文件内容:" + s);}}
}

四、编译后的底层实现

  1. 用ILSpy反编译DLL文件
    • ILSpy就是个反编译工具,能把DLL文件变回C#代码,方便咱们研究。
    • 把DLL文件加载到ILSpy里,就能看到编译后的代码啦。
[CompilerGenerated]
private sealed class <>c__DisplayClass0_0 : IAsyncStateMachine
{public int <>1__state;public AsyncTaskMethodBuilder <>t__builder;public string[] args;private string <>s__1;private string <>s__3;private string <>s__6;private HttpClient <httpClient>__4;private string <html>__5;private string <txt>__2;private string <filename>__7;private void MoveNext(){int num = this.<>1__state;try{TaskAwaiter<string> awaiter;TaskAwaiter awaiter2;switch (num){default:this.<httpClient>__4 = new HttpClient();goto case 0;case 0:try{awaiter = this.<httpClient>__4.GetStringAsync("https://www.baidu.com").GetAwaiter();if (!awaiter.IsCompleted){num = this.<>1__state = 0;this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;}}catch (Exception exception){this.<>1__state = -2;this.<>t__builder.SetException(exception);return;}this.<html>__5 = awaiter.GetResult();Console.WriteLine(this.<html>__5);this.<txt>__2 = "hello yz";this.<filename>__7 = @"E:\temp\1.txt";awaiter2 = File.WriteAllTextAsync(this.<filename>__7, this.<txt>__2).GetAwaiter();if (!awaiter2.IsCompleted){num = this.<>1__state = 1;this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);return;}break;case 1:awaiter2 = this.<>s__1;this.<>s__1 = null;num = this.<>1__state = -1;break;}awaiter2.GetResult();Console.WriteLine("写入成功");this.<>s__3 = null;awaiter = File.ReadAllTextAsync(this.<filename>__7).GetAwaiter();if (!awaiter.IsCompleted){num = this.<>1__state = 2;this.<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);return;}this.<>s__6 = awaiter.GetResult();Console.WriteLine("文件内容:" + this.<>s__6);this.<>s__6 = null;this.<>t__builder.SetResult();}catch (Exception exception){this.<>1__state = -2;this.<>t__builder.SetException(exception);return;}this.<>1__state = -1;}void IAsyncStateMachine.MoveNext(){// This method is implemented by the compiler-generated code.}[DebuggerHidden]private void SetStateMachine(IAsyncStateMachine stateMachine){this.<>t__builder.SetStateMachine(stateMachine);}void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine){this.SetStateMachine(stateMachine);}
}
  1. 看看编译后的状态机代码
    • 分析状态机类的结构,看看都有啥变量、MoveNext方法长啥样。
    • 瞧瞧awaiter咋用的,状态咋切换的。
  2. 理解MoveNext方法是干啥的
    • MoveNext就是状态机的发动机,它决定了异步方法咋执行。
    • 在这个方法里,会根据当前状态执行对应的代码,碰到await就暂停,安排好后续咋继续。

五、总结

  1. 异步方法编译过程回顾
    • 再唠唠async方法咋被编译成状态机的,状态机又咋根据await拆分方法、驱动异步操作的。
  2. await到底在干啥
    • 说白了,await根本不是真的“等待”,而是靠状态机和等待器来实现的异步协作。
    • 强调一下异步编程的好处,比如响应快、省资源、能扛更多活儿,还有啥场景适合用它。

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

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

相关文章

安全教育知识竞赛答题小程序怎么做

以下是制作安全教育知识竞赛答题小程序的一般步骤&#xff1a; 一、准备阶段 注册小程序账号&#xff1a;前往微信公众平台&#xff0c;注册一个小程序账号&#xff0c;主体类型可根据实际情况选择个人或企业等&#xff0c;注册成功后登录获取appid。 下载安装开发工具&#x…

记录待办事项的便签软件有没有推荐的?

在快节奏的现代生活中&#xff0c;我们每天都要处理大量的工作任务和生活琐事&#xff0c;稍有不慎就可能遗漏重要事项。你是否经常遇到这样的情况&#xff1a;明明记得有件事要做&#xff0c;却怎么也想不起来是什么&#xff1b;或者手头同时有好几项任务&#xff0c;却不知道…

实验四 中断实验

一、实验目的 掌握中断服务程序的编写。 二、实验电路 三、实验内容 1&#xff0e;实验用PC机内部的中断控制器8259A&#xff0c;中断源用TPC-ZK实验箱上的单脉冲电路&#xff0c;将单脉冲电路的输出接中断请求信号IRQ&#xff0c;每按一次单脉冲按键产生一次…

React 项目src文件结构

SCSS 组件库 SCSS为预处理器 支持除原生CSS外的其他语句 别名路径 在项目下的第一级目录就加入craco.config.js文件并且修改packpage.js 中的部分 // 扩展webpage的配置const path require(path)module.exports {// exports配置webpack:{// 配置别名alias:{:path.resolve(__d…

Cursor入门教程-JetBrains过度向

Cursor使用笔记 **前置&#xff1a;**之前博主使用的是JetBrains的IDE&#xff0c;VSCode使用比较少&#xff0c;所以会尽量朝着JetBrains的使用习惯及样式去调整。 一、设置语言为中文 如果刚上手Cursor&#xff0c;那么肯定对Cursor中的众多选项配置项不熟悉&#xff0c;这…

Linux上位机开发实践(SoC和MCU的差异)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 soc一般是指跑linux的芯片&#xff0c;而mcu默认是跑rtos的芯片&#xff0c;两者在基本原理方面其实差异不大。只不过&#xff0c;前者由于性能的原…

离线导出和安装Python库

详细介绍&#xff1a;离线导出和安装Python库 常用命令&#xff1a; 生成requirement.txt文件 pip freeze > requirement.txt离线批量下载库 pip download -d packages -r requirement.txt离线批量安装库 pip install --no-index --find-links./ -r requirement.txt

基于Vue Node.js的电影售票网站的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!

摘要 互联网技术的成熟和普及&#xff0c;势必会给人们的生活方式带来不同程度的改变。越来越多的经营模式中都少不了线上运营&#xff0c;互联网正强力推动着社会和经济发展。国人对民族文化的自信和不同文化的包容&#xff0c;再加上电影行业的发展&#xff0c;如此繁荣吸引…

利用 Python 和 AI 技术创作独特的图像艺术作品

1. 项目目标 生成艺术作品&#xff1a;利用 AI 模型&#xff08;如 Stable Diffusion&#xff09;生成具有艺术风格的图像。自定义风格&#xff1a;通过文本提示&#xff08;prompt&#xff09;控制图像的艺术风格&#xff08;如赛博朋克、印象派、超现实主义等&#xff09;。…

XR技术赋能艺术展演|我的宇宙推动东方美学体验化

本次广州展览现场引入我的宇宙XR体验模块&#xff0c;通过空间计算与动作捕捉技术&#xff0c;让观众在潮玩艺术氛围中体验虚拟互动&#xff0c;打造“看得懂也玩得动”的展演新场景。 作为科技与文化融合的推动者&#xff0c;我的宇宙正在以“体验科技”为媒介&#xff0c;为潮…

接口的集成测试步骤

一、集成测试是什么 ‌接口的集成测试‌是指在软件开发过程中&#xff0c;将各个模块或组件按照设计要求组合在一起&#xff0c;并测试它们之间的接口是否能够正确交互和协同工作的过程。集成测试是软件开发中的一个重要阶段&#xff0c;通常在单元测试之后进行&#xff0c;目的…

上门服务 APP 30 亿营收商业模式在乌干达的技术赋能与实践

不久前&#xff0c;非洲乌干达出现黑人女技师提供上门足疗服务的消息引发关注。据了解&#xff0c;当地一次40分钟的上门按摩服务仅需约40元人民币&#xff0c;价格仅为国内同类服务的十分之一。这一现象折射出全球健康服务行业正在经历的数字化转型浪潮。 国内领先的上门服务平…

go语言学习笔记:gin + gorm + mysql 用户增删改查案例入门

大家好&#xff0c;我是此林。 Golang 语言现在已经成为了编程的趋势&#xff0c;毕竟是大厂背书嘛&#xff0c;Google 研发的。 目前很多云原生项目都是基于 go 来编写的&#xff0c;比如&#xff1a; Kubernetes (K8s)​ 容器编排系统&#xff0c; Docker​ 容器化技术&…

探索亮数据Web Unlocker API:让谷歌学术网页科研数据 “触手可及”

本文目录 一、引言二、Web Unlocker API 功能亮点三、Web Unlocker API 实战1.配置网页解锁器2.定位相关数据3.编写代码 四、Web Scraper API技术亮点 五、SERP API技术亮点 六、总结 一、引言 网页数据宛如一座蕴藏着无限价值的宝库&#xff0c;无论是企业洞察市场动态、制定…

SpringBoot整合POI实现Excel文件的导出与导入

使用 Apache POI 操作 Excel文件,系列文章: 《SpringBoot整合POI实现Excel文件的导出与导入》 《SpringMVC实现文件的上传与下载》 《C#使用NPOI导出Excel文件》 《NPOI使用手册》 1、Apache POI 的介绍 Apache POI 是一个基于 Java 的开源库,专为读写 Microsoft Office 格…

构建用户友好的记账体验 - LedgerX交互设计与性能优化实践

构建用户友好的记账体验 - LedgerX交互设计与性能优化实践 发布日期: 2025-04-16 引言 在财务管理应用领域&#xff0c;技术实力固然重要&#xff0c;但最终决定用户留存的往往是日常使用体验。本文作为LedgerX技术博客的第二篇&#xff0c;将深入探讨我们如何通过精心的交互…

如何用AI辅助软件产品原型设计及工具推荐

以下是针对软件产品原型设计的 AI辅助工具推荐&#xff0c;涵盖国内外主流工具&#xff0c;结合功能特点、优劣势及适用场景分析&#xff0c;并标注是否为国内软件及付费情况&#xff1a; 一、国内工具推荐 1. 墨刀AI&#xff08;MockingBot AI&#xff09; 特点&#xff1a;…

MySQL的MVCC机制详解

1. 什么是MVCC&#xff1f; MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是数据库系统中用于实现并发控制的一种技术。它通过保存数据在某个时间点的快照来实现&#xff0c;使得在同一个数据行上可以同时存在多个版本&#xff0…

C语言数字图像处理---2.31统计滤波器

本文介绍空域滤波器中的一种:统计滤波器 [定义与算法] 统计滤波(Statistic Filter)定义:基于图像处理中的邻域统计方法,对邻域内的像素信息进行统计,如基于均值和方差的信息,用于平滑或去噪图像,同时保留边缘信息。 算法步骤如下: 统计滤波器的优点和缺点主要包…

计算机视觉相机模型与标定:如何让计算机“看懂”三维世界?

计算机视觉相机模型与标定:如何让计算机“看懂”三维世界? 一、前言二、相机模型基础​2.1 针孔相机模型​2.1.1 模型原理​2.1.2 代码示例​2.2 透视变换与相机内参​2.2.1 透视变换矩阵​2.2.2 内参矩阵的作用​2.3 相机外参​2.3.1 世界坐标系与相机坐标系的转换​2.3.2 外…