【C# TAP 异步编程】二 、await 标志

2021/12/17 22:19:32

本文主要是介绍【C# TAP 异步编程】二 、await 标志,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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 等待异步方法运行的结果。

 



这篇关于【C# TAP 异步编程】二 、await 标志的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程