注意:本文章仅供个人学习用途,并不保证解释和想法是正确的,
新建webapi项目,在ValuesController中输入如下代码:
private static int TId()
{
return Thread.CurrentThread.ManagedThreadId;
}
// GET api/<controller>
public async Task<IEnumerable<string>> Get()
{
Debug.WriteLine($"thread id {TId()} before Task.Run", "Debug");
await Task.Run(() =>
{
Debug.WriteLine($"thread id {TId()} in Task.Run", "Debug");
});
Debug.WriteLine($"thread id {TId()} after Task.Run", "Debug");
return new string[] { "value1", "value2" };
}
通过.NET Reflector 7.0反编译webapi的dll
async关键字消失了,它被编译成了如下方法:
[AsyncStateMachine(typeof(<Get>d__2)), DebuggerStepThrough]
public Task<IEnumerable<string>> Get()
{
<Get>d__2 stateMachine = new <Get>d__2 {
<>4__this = this,
<>t__builder = AsyncTaskMethodBuilder<IEnumerable<string>>.Create(),
<>1__state = -1
};
//这里Start状态机
stateMachine.<>t__builder.Start<<Get>d__2>(ref stateMachine);
//new一个状态机stateMachine并且设置相关属性,__this是Controller,
//__builder是AsyncTaskMethodBuilder<IEnumerable<string>>
//__state = -1 ,方便起见去掉了编译器生成的前缀
//然后直接返回__builder的Task
return stateMachine.<>t__builder.Task;
}
状态机的MoveNext方法:
private void MoveNext()
{
IEnumerable<string> enumerable;
int num = this.<>1__state;
try
{
TaskAwaiter awaiter;
if (num != 0)
{
Debug.WriteLine(string.Format("thread id {0} before Task.Run", ValuesController.TId()), "Debug");
if (ValuesController.<>c.<>9__2_0 == null)
{
Action action1 = ValuesController.<>c.<>9__2_0;
}
//await消失了,被编译成下面的语句
awaiter = Task.Run(ValuesController.<>c.<>9__2_0 = new Action(ValuesController.<>c.<>9.<Get>b__2_0)).GetAwaiter();
if (!awaiter.IsCompleted)
{
//awaiter.IsCompleted其实就是Task.IsCompleted
//awaiter没有完成完成,再调用AsyncTaskMethodBuilder<TResult>.AwaitUnsafeOnCompleted
//方法设置awaiter和状态机stateMachine来达到某种目的,然后直接返回
this.<>1__state = num = 0;
this.<>u__1 = awaiter;
ValuesController.<Get>d__2 stateMachine = this;
this.<>t__builder.AwaitUnsafeOnCompleted<TaskAwaiter, ValuesController.<Get>d__2>(ref awaiter, ref stateMachine);
return;
}
}
else
{
//awaiter为什么要把值设置回去,目前还没看懂。
awaiter = this.<>u__1;
this.<>u__1 = new TaskAwaiter();
//状态恢复初始值
this.<>1__state = num = -1;
}
//Get Result获取结果
awaiter.GetResult();
Debug.WriteLine(string.Format("thread id {0} after Task.Run", ValuesController.TId()), "Debug");
string[] textArray1 = new string[] { "value1", "value2" };
enumerable = textArray1;
}
catch (Exception exception)
{
this.<>1__state = -2;
this.<>t__builder.SetException(exception);
return;
}
this.<>1__state = -2;
this.<>t__builder.SetResu