编辑
2025-09-24
C#
00

目录

摘要
正文

摘要

Async/Await是C# 5引入的关键字,旨在提高用户界面响应能力和对Web资源的访问能力,同时它使异步代码的编写变得更加容易。在C#中,异步编程可以使代码更加简洁、高效和易于维护。异步编程的一个重要挑战是处理异步操作完成后的结果,以避免阻塞主线程并保持用户界面的响应性。

  1. 并非一次完成,而且分多次完成
  2. 并非由同一个线程完成,而是线程池每次动态分配一个线程来处理;

正文

microsoft 的一篇文档 Task asynchronous programming model,它描述了在异步编程中控制流是如何在方法之间移动的。

image.png

执行步骤

  • CLR创建一个状态机,这个状态机的操作数默认值为-1。
  • 开始执行状态机
  • 状态机通过操作数来选定执行路径
  • 状态机调用GetAwaiter方法来获取一个等待者对象awaiter,它的类型为TaskAwaiter
  • 状态机获取awaiter后,查询其IsCompleted属性。
  • 若IsCompleted为True,则操作已经以同步方式完成,状态机继续执行以处理结果。
  • 若IsCompleted为False,则操作将以异步方式来完成,状态机调用awaiter的OnCompleted方法并向它传递一个委托(引用状态机的MoveNext来实现工作流状态的变迁)。这时状态机允许线程返回原地以执行其它代码。
  • 将来某个时候,awaiter会在完成时调用委托以执行MoveNext,这时可根据状态机中的字段知道如何到达代码中的正确位置,使方法能够从它当初离开的位置继续。
  • 调用awaiter的GetResult方法获取结果,并进行处理。
  • 状态机执行完毕后,垃圾回收器会回收任何内存。

写个例子

C#
internal class Program { static async Task Main(string[] args) { var len = await DownloadHtmlAsync("http://www.baidu.com", "baidu.txt"); Console.WriteLine(len); } static async Task<int> DownloadHtmlAsync(string url, string filename) { using (HttpClient client = new HttpClient()) { string html = await client.GetStringAsync(url); await File.WriteAllTextAsync("./" + filename, html); return html.Length; } } }

我们用ILSpy反编译一下DLL文件

将.net版本选到4.0版本

image.png

image.png

image.png

await,async 是语法糖,最终编译成状态机调用

image.png

async/await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁、易懂、易维护的异步代码。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!