[toc]

# C#5.0 async 转换成 C#4.0 原生代码

先去这个网站: https://sharplab.io

然后输入以下代码

using System;
using System.Threading.Tasks;
public class C {
static async Task Main(string[] args)
{
await StartSilo();

    Console.WriteLine("开启CardServer!");

    Console.ReadLine();
}
private static async Task StartSilo()
{
}

}

然后将右边也设置为 C#, 就会转换成原生 C# 代码

# 异步状态机的原生代码

转换后的代码如下所示

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default DebuggableAttribute.DebuggingModes.DisableOptimizations DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion(“0.0.0.0”)]
[module: UnverifiableCode]
public class C
{
[CompilerGenerated]
private sealed class

d__0 : IAsyncStateMachine
{
public int <>1__state;

    public AsyncTaskMethodBuilder <>t\_\_builder;

    public string\[\] args;

    private TaskAwaiter <>u\_\_1;

    private void MoveNext()
    {
        int num = <>1\_\_state;
        try
        {
            TaskAwaiter awaiter;
            if (num != 0)
            {
                awaiter = StartSilo().GetAwaiter();
                if (!awaiter.IsCompleted)
                {
                    num = (<>1\_\_state = 0);
                    <>u\_\_1 = awaiter;
                    <Main>d\_\_0 stateMachine = this;
                    <>t\_\_builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                    return;
                }
            }
            else
            {
                awaiter = <>u\_\_1;
                <>u\_\_1 = default(TaskAwaiter);
                num = (<>1\_\_state = -1);
            }
            awaiter.GetResult();
            Console.WriteLine("开启CardServer!");
            Console.ReadLine();
        }
        catch (Exception exception)
        {
            <>1\_\_state = -2;
            <>t\_\_builder.SetException(exception);
            return;
        }
        <>1\_\_state = -2;
        <>t\_\_builder.SetResult();
    }

    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);
    }
}

\[CompilerGenerated\]
private sealed class <StartSilo>d\_\_1 : IAsyncStateMachine
{
    public int <>1\_\_state;

    public AsyncTaskMethodBuilder <>t\_\_builder;

    private void MoveNext()
    {
        int num = <>1\_\_state;
        try
        {
        }
        catch (Exception exception)
        {
            <>1\_\_state = -2;
            <>t\_\_builder.SetException(exception);
            return;
        }
        <>1\_\_state = -2;
        <>t\_\_builder.SetResult();
    }

    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);
    }
}

\[AsyncStateMachine(typeof(<Main>d\_\_0))\]
\[DebuggerStepThrough\]
private static Task Main(string\[\] args)
{
    <Main>d\_\_0 stateMachine = new <Main>d\_\_0();
    stateMachine.<>t\_\_builder = AsyncTaskMethodBuilder.Create();
    stateMachine.args = args;
    stateMachine.<>1\_\_state = -1;
    stateMachine.<>t\_\_builder.Start(ref stateMachine);
    return stateMachine.<>t\_\_builder.Task;
}

\[AsyncStateMachine(typeof(<StartSilo>d\_\_1))\]
\[DebuggerStepThrough\]
private static Task StartSilo()
{
    <StartSilo>d\_\_1 stateMachine = new <StartSilo>d\_\_1();
    stateMachine.<>t\_\_builder = AsyncTaskMethodBuilder.Create();
    stateMachine.<>1\_\_state = -1;
    stateMachine.<>t\_\_builder.Start(ref stateMachine);
    return stateMachine.<>t\_\_builder.Task;
}

}

笔者尝试写一个类似的非编译时的 C# 代码,如下所示:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;

namespace SharpDemo
{
class Program
{
///


/// Main 函数的状态机
///

class Main_D_0 : IAsyncStateMachine
{
public int Ostate;
public AsyncTaskMethodBuilder t_builder;

        public string\[\] args;

        private TaskAwaiter u\_1;

        public void MoveNext()
        {
            int num = Ostate;
            try
            {
                TaskAwaiter awaiter;
                if (num != 0)
                {
                    awaiter = StartSilo().GetAwaiter();
                    if (!awaiter.IsCompleted)
                    {
                        num = (Ostate = 0);
                        u\_1 = awaiter;
                        Main\_D\_0 stateMachine = this;
                        t\_builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
                        return;
                    }
                }
                else
                {
                    awaiter = u\_1;
                    u\_1 = default(TaskAwaiter);
                    num = (Ostate = -1);
                }
                awaiter.GetResult();
                Console.WriteLine("开启CardServer!");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Ostate = -2;
                t\_builder.SetException(e);
                return;
            }
            Ostate = -2;
            t\_builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            this.MoveNext();
        }

        public void SetStateMachine(IAsyncStateMachine stateMachine)
        {
            
        }
        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }

    class StartSilo\_D\_1 : IAsyncStateMachine
    {
        public int OState;
        public AsyncTaskMethodBuilder t\_builder;

        public void MoveNext()
        {
            int num = OState;
            try
            {

            }
            catch (Exception exception)
            {
                OState = -2;
                t\_builder.SetException(exception);
                return;
            }
            OState = -2;
            t\_builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            this.MoveNext();
        }

        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }


    static void Main(string\[\] args)
    {
        Main\_(args);
    }

    private static Task Main\_(string\[\] args)
    {
        Main\_D\_0 stateMachine = new Main\_D\_0();
        stateMachine.t\_builder = AsyncTaskMethodBuilder.Create();
        stateMachine.args = args;
        stateMachine.Ostate = -1;
        stateMachine.t\_builder.Start(ref stateMachine);
        return stateMachine.t\_builder.Task;
    }

    private static Task StartSilo()
    {
        StartSilo\_D\_1 stateMachine = new StartSilo\_D\_1();
        stateMachine.t\_builder = AsyncTaskMethodBuilder.Create();
        stateMachine.OState = -1;
        stateMachine.t\_builder.Start(ref stateMachine);
        return stateMachine.t\_builder.Task;
    }

}

}

可以看到,某个类中含有 **async 标记符的函数会被编译成一个异步状态机类,其中,状态用 OState 这个整数来标记,失败这个标记就返回 - 2, 如果一个函数里有多个 await 的时候,就会编译成 switch (Ostate) 来选择当前的状态,其中,不同状态与状态之间的代码会包裹在这些 state 的 switch 块 ** 之内.

大概就是这样的一个状态机.

每个有 async 的函数都会被编译成一个异步状态机类,每个 await 和下个 await 之间都是一个新的状态。每个 await 都是一个 TaskAwaiter, 通过 TaskAwaiter 的 IsCompleted 来判断对应的 async 状态机是否已经完成