【C# TAP 异步编程】一 、async 修饰符(标记)


async的作用:

1、async是一个标记,告诉编译器这是一个异步方法。

2、编译器会根据这个标志生成一个异步状态机。

3、编译器将原异步方法中的代码清空,写入状态机的配置,原先异步方法中的代码被封装入状态机。

 4、async 关键字是上下文关键字,原因在于只有当它修饰方法、lambda 表达式或匿名方法时,它才是关键字。 在所有其他上下文中,都会将其解释为标识符。

5、如果 async 关键字修改的方法不包含 await 表达式或语句,则该方法将同步执行。

async 的异步方法的刨析

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反编译后代码:

以下开始分析反编译后的源代码:

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

1、编译器 async标记给异步方法生成 一个叫AsyncStateMachine异步状态机的特性附着于方法上,告诉CLR这是一个异步状态机。如下图所示:

编译器将原异步方法中的代码清空,写入状态机的配置,原先异步方法中的代码被封装入状态机。

2、编译器还生成一个异步状态机的类。

该类继承IAsyncStateMachine接口。IAsyncStateMachine接口有两个方法:MoveNext()、SetStateMachine();

该类除了以上两个方法,还有重要两字段:AsyncTaskMethodBuilder  表示返 回任务的异步方法生成器。state 状态。

源代码中返回值(return 3;)被封装入异步状态机的<>t__builder 字段中。最后的返回值 return stateMachine.<>t__builder.Task 是Task类型。

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

注意:awaiter.GetResult()、awaiter.Result都会阻塞线程

返回类型

异步方法可以具有以下返回类型:

  • Task:对于事件处理程序以外的不返回值的方法,应返回 Task
  • Task(对于返回值的异步方法)。
  • void:对于事件处理程序,事件使用的是void类型的委托。
  • ValueTask C#7.0
  • 使用 IAsyncEnumerable 的异步流C#8.0

相信查看:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/async-return-types

相关