【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<TResult>类,这两个功能必须详细理解。
1、编译器 async标记给异步方法生成 一个叫AsyncStateMachine异步状态机的特性附着于方法上,告诉CLR这是一个异步状态机。如下图所示:
编译器将原异步方法中的代码清空,写入状态机的配置,原先异步方法中的代码被封装入状态机。
2、编译器还生成一个异步状态机的类。
该类继承IAsyncStateMachine接口。IAsyncStateMachine接口有两个方法:MoveNext()、SetStateMachine();
该类除了以上两个方法,还有重要两字段:AsyncTaskMethodBuilder<TResult> 表示返 回任务的异步方法生成器。state 状态。
源代码中返回值(return 3;)被封装入异步状态机的<>t__builder 字段中。最后的返回值 return stateMachine.<>t__builder.Task 是Task<TResult>类型。
通过IL代码我们就可以清楚的得知async就是语法糖。
注意:awaiter.GetResult()、awaiter.Result都会阻塞线程
返回类型
异步方法可以具有以下返回类型:
- Task:对于事件处理程序以外的不返回值的方法,应返回 Task
- Task<TResult>(对于返回值的异步方法)。
void
:对于事件处理程序,事件使用的是void类型的委托。- ValueTask<TResult> C#7.0
- 使用 IAsyncEnumerable<T> 的异步流C#8.0
相信查看:https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/async/async-return-types