await的作用:
1、await是一个标志,告诉编译器生成一个等待器来等待异步方法运行的结果。
2、一个await对应一个等待器awaiter
await 的异步方法的刨析
通过一段代码来了解await,把这编译后,用ILspy 反编译。
namespace MyTask; class Program { public static void Main(string[] args) { Task<string> baconTask = FryBaconAsync(3); baconTask.ContinueWith(t =>Console.WriteLine(t.Result)); Console.Read(); } static async Task<string> FryBaconAsync(int slices) { HttpClient httpClient=new HttpClient(); string content = await httpClient.GetStringAsync("https://www.cnblogs.com/cdaniu/p/15681416.html"); return content; //整数3和Task<int>不存在隐形转化啊,怎么就可以return 3; 如果你也存在这个疑问 请继续往下阅读,接下去详细分析。 } }
用ILspy 反编译后的完整代码:
// MyTask.Program using System; using System.Diagnostics; using System.Net.Http; using System.Runtime.CompilerServices; using System.Threading.Tasks; using MyTask; [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] internal class Program { [Serializable] [CompilerGenerated] private sealed class <>c { [System.Runtime.CompilerServices.Nullable(0)] public static readonly <>c <>9 = new <>c(); [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1, 1 })] public static Action<Task<string>> <>9__0_0; internal void <Main>b__0_0(Task<string> t) { Console.WriteLine(t.Result); } } [CompilerGenerated] private sealed class <FryBaconAsync>d__1 : IAsyncStateMachine { public int <>1__state; [System.Runtime.CompilerServices.Nullable(0)] public AsyncTaskMethodBuilder<string> <>t__builder; public int slices; [System.Runtime.CompilerServices.Nullable(0)] private HttpClient <httpClient>5__1; [System.Runtime.CompilerServices.Nullable(0)] private string <content>5__2; [System.Runtime.CompilerServices.Nullable(0)] private string <>s__3; [System.Runtime.CompilerServices.Nullable(new byte[] { 0, 1 })] private TaskAwaiter<string> <>u__1; private void MoveNext() { int num = <>1__state; string result; try { TaskAwaiter<string> awaiter; if (num != 0) { <httpClient>5__1 = new HttpClient(); awaiter = <httpClient>5__1.GetStringAsync("https://www.cnblogs.com/cdaniu/p/15681416.html").GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <FryBaconAsync>d__1 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } } else { awaiter = <>u__1; <>u__1 = default(TaskAwaiter<string>); num = (<>1__state = -1); } <>s__3 = awaiter.GetResult(); <content>5__2 = <>s__3; <>s__3 = null; result = <content>5__2; } catch (Exception exception) { <>1__state = -2; <httpClient>5__1 = null; <content>5__2 = null; <>t__builder.SetException(exception); return; } <>1__state = -2; <httpClient>5__1 = null; <content>5__2 = null; <>t__builder.SetResult(result); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } } public static void Main(string[] args) { Task<string> baconTask = FryBaconAsync(3); baconTask.ContinueWith(<>c.<>9__0_0 ?? (<>c.<>9__0_0 = new Action<Task<string>>(<>c.<>9.<Main>b__0_0))); Console.Read(); } [AsyncStateMachine(typeof(<FryBaconAsync>d__1))] [DebuggerStepThrough] private static Task<string> FryBaconAsync(int slices) { <FryBaconAsync>d__1 stateMachine = new <FryBaconAsync>d__1(); stateMachine.<>t__builder = AsyncTaskMethodBuilder<string>.Create(); stateMachine.slices = slices; stateMachine.<>1__state = -1; stateMachine.<>t__builder.Start(ref stateMachine); return stateMachine.<>t__builder.Task; } }View Code
编译器根据await生成一个等待器awaiter,程序通过return;把控制权还给了调用函数,用这个awaiter 等待异步方法运行的结果。