async await实现原理,反编译源代码解读
1.Task中async await
public class ThreadAsync { public static void Show() { Console.WriteLine("Show:Start"); TestTwo(); Console.WriteLine("Show:End"); } public static async void TestTwo() { Console.WriteLine("******************** TestTwo ***********************"); Console.WriteLine("AAA:This is step one: Begain"); await Task.Run(() => { Thread.Sleep(1000); Console.WriteLine("BBB:This is Await_Method_One"); }); Console.WriteLine("CCC:This is step between await one and await two"); await Task.Run(() => { Thread.Sleep(1000); Console.WriteLine("DDD:This is Await_Method_Two"); }); Console.WriteLine("EEE:This is step End"); } }
执行结果。
2.反编译后看源代码
public class ThreadAsync { [CompilerGenerated] private sealed class <TestTwo>d__1 : IAsyncStateMachine { public int <>1__state; public AsyncVoidMethodBuilder <>t__builder; private TaskAwaiter <>u__1; private void MoveNext() { int num = <>1__state; try { TaskAwaiter awaiter; TaskAwaiter awaiter2; if (num != 0) { if (num == 1) { awaiter = <>u__1; <>u__1 = default(TaskAwaiter); num = (<>1__state = -1); goto IL_012c; } Console.WriteLine("******************** TestTwo ***********************"); Console.WriteLine("AAA:This is step one: Begain"); awaiter2 = Task.Run(delegate { Thread.Sleep(1000); Console.WriteLine("BBB:This is Task_Method"); }).GetAwaiter(); if (!awaiter2.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter2; <TestTwo>d__1 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine); return; } } else { awaiter2 = <>u__1; <>u__1 = default(TaskAwaiter); num = (<>1__state = -1); } awaiter2.GetResult(); Console.WriteLine("CCC:This is step between await one and await two"); awaiter = Task.Run(delegate { Thread.Sleep(1000); Console.WriteLine("DDD:This is Task_Method"); }).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__1 = awaiter; <TestTwo>d__1 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_012c; IL_012c: awaiter.GetResult(); Console.WriteLine("EEE:This is step End"); } catch (Exception exception) { <>1__state = -2; <>t__builder.SetException(exception); return; } <>1__state = -2; <>t__builder.SetResult(); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine([System.Runtime.CompilerServices.Nullable(1)] IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine([System.Runtime.CompilerServices.Nullable(1)] IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } public static void Show() { Console.WriteLine("Show:Start"); TestTwo(); Console.WriteLine("Show:End"); } [AsyncStateMachine(typeof(<TestTwo>d__1))] [DebuggerStepThrough] public static void TestTwo() { <TestTwo>d__1 stateMachine = new <TestTwo>d__1(); stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create(); stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); } }
3.编译后的TestTwo方法的内容发生了较大的变化。其中多了一个类<TestTwo>d__1, 该类继承接口IAsyncStateMachine,看名字是一个异步状态机,实现MoveNext方法和SetStateMachine方法。
// System.Runtime.CompilerServices.IAsyncStateMachine using System.Runtime.CompilerServices; [NullableContext(1)] public interface IAsyncStateMachine { void MoveNext(); void SetStateMachine(IAsyncStateMachine stateMachine); }
4.查看编译后的TestTwo方法,有4个步骤。
4.1 创建状态机,即new一个<TestTwo>d__1()对象
4.2 给状态机类的AsyncVoidMethodBuilder属性赋值,(Task有返回是AsyncTaskMethodBuilder<T>对象)
4.3 给状态机的状态<>1__state赋值为-1.后面会看到,第一个await方法,匹配的状态值<>1__state是0,第二个匹配的状态值<>1__state为1
4.4 启动状态机对象中异步方法AsyncVoidMethodBuilder属性,并把状态机对象作为参数传入。AsyncVoidMethodBuilder.Start(ref sateMachine)方法是触发传入参数stateMachine的MoveNext()方法
5.进入MoveNext方法,Task.Run().GetAwaiter得到一个TaskAwaiter类
5.1第一次执行MoveNext,状态值 <>1__state是-1。把TaskAwaiter和当前状态机对象当作参数,传入AsyncVoidMethodBuilder.AwaitUnsafeOnCompleted方法(该方法比较深,大概的意思就是监听Task的OnCompleted事件)。并把状态值<>1__state改为0.当任务完成的时候,会触发传入参数stateMachine的MoveNext方法。
5.2 当第一个await完成后,会继续触发当前状态机对象的MoveNext方法,第二次执行MoveNext,这时<>1__state是0,即num是0.
1.会得到第一个await方法的结果。awaiter2.GetResult();
2.会得到第2个Task的TaskAwaiter对象,然后传入AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine)方法。等待Task.IsCompleted后,继续触发事件,执行当前对象(作为参数stateMachine传入)的MoveNext.
3.把状态值改为1.
5.3 当第二个await方法执行完毕后,会再次触发MoveNext,状态值<>1__state是1.直接跳到获取第二个await方法获取结果。
总结,大概就是每执行一步,修改状态<>1__state的值,通过AsyncVoidMethodBuilder类的AwaitUnsafeOnCompleted方法,监听TaskAwaiter的OnCompleted方法,并触发当前的状态机的MoveNext方法。关于AwaitUnsafeOnCompleted的方法的底层调用,日后有时间可以查看源码。AsyncTaskMethodBuilder.cs (dot.net)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2020-06-05 大数据处理中,不要用ORM框架,要少造对象。可以使用索引。