【C# 异步方法】async/await

async标志

async总结:

async是一个标志,告诉编译器这是一个异步方法。编译器根据这个标志 将带有async标志的异步方法转化为一个异步状态机。

Task背后有一个名为的TaskScheduler的类来处理Task在Thread上的执行。可以这样说TaskScheduler和Task就是.NET4.0中异步和并发操作的基础,也是我们写代码时不二的选择。

返回值为async Task<int>的异步方法的刨析

async是什么呢?我通过一段代码来了解,案例源代码如下:

namespace MyTask;
  class Program
    {
        public static  void Main(string[] args)
        {
            Task<int> baconTask =  FryBaconAsync(3);
            Console.Read();
        }
        static async Task<int> FryBaconAsync(int slices)
        {
 
        return  3; //整数3和Task<int>不存在隐形转化啊,怎么就可以return 3; 如果你也存在这个疑问 请继续往下阅读,接下去详细分析。
        }
}

ILspy反编译后代码:

【C# 异步方法】async/await

// MyTask.Program
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using MyTask;

[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal class Program
{
    [CompilerGenerated]
    private sealed class <FryBaconAsync>d__1 : IAsyncStateMachine
    {
        public int <>1__state;

        [System.Runtime.CompilerServices.Nullable(0)]
        public AsyncTaskMethodBuilder<int> <>t__builder;

        public int slices;

        private void MoveNext()
        {
            int num = <>1__state;
            int result;
            try
            {
                result = 3;
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>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<int> baconTask = FryBaconAsync(3);
        Console.Read();
    }

    [AsyncStateMachine(typeof(<FryBaconAsync>d__1))]
    [DebuggerStepThrough]
    private static Task<int> FryBaconAsync(int slices)
    {
        <FryBaconAsync>d__1 stateMachine = new <FryBaconAsync>d__1();
        stateMachine.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
        stateMachine.slices = slices;
        stateMachine.<>1__state = -1;
        stateMachine.<>t__builder.Start(ref stateMachine);
        return stateMachine.<>t__builder.Task;
    }
}

以下开始分析IL代码和源代码:

用到的知识点:IAsyncStateMachine接口、AsyncTaskMethodBuilder<TResult>类,这两个功能必须详细理解。

编译器具体的执行过程:

1、编译器会根据async标记给异步方法生成 一个叫AsyncStateMachine异步状态机的特性附着于方法上,告诉运行时这是一个异步状态机。

2、然后生成一个异步状态机的类,该类继承IAsyncStateMachine接口。IAsyncStateMachine接口有两个方法:MoveNext()、SetStateMachine();该类除了以上两个方法,还有重要两字段
AsyncTaskMethodBuilder<TResult>  表示返回任务的异步方法生成器。state 状态。

源代码中return 3;在MoveNext()方法中被打包进了AsyncTaskMethodBuilder<TResult> 异步方法生成器中。最后返回任务(返回值)是通过异步方法生成器stateMachine.<>t__builder.Task获取。该属性类型是Task<TResult>。

通过IL代码我们就可以清楚的得知async就是语法糖。

 

【C# 异步方法】async/await

 

 【C# 异步方法】async/await

 

 

到此开头留下为什么能返回return 3;的问题就解答完了。

 

上一篇:简单的线程池(五)


下一篇:Java 定时器