C#异步的世界(下)

这篇文章主要介绍了C#异步的世界(下),对异步感兴趣的同学,可以参考下

方法签名完全一致,只是里面的内容变成了一个状态机GetUrlStringAsyncdStateMachine 的调用。此状态机就是编译器自动创建的。下面来看看神秘的状态机是什么鬼:


private sealed class GetUrlStringAsyncdStateMachine : IAsyncStateMachine
{
    public int _state;
    public MyAsyncTest _this;
    private string _str1;
    public AsyncTaskMethodBuilder<string> _builder;
    private TaskAwaiter taskAwaiter1;
    private TaskAwaiter<string> taskAwaiter2;    //异步方法的三个形参都到这里来了
    public HttpClient http;
    public int time;
    public string url;

    private void MoveNext()
    {
        string str;
        int num = this._state;
        try
        {
            TaskAwaiter awaiter;
            MyAsyncTest.GetUrlStringAsyncdStateMachine d__;
            string str2;
            switch (num)
            {
                case 0:
                    break;

                case 1:
                    goto Label_00CD;

                default:                    //这里是异步方法 await Task.Delay(time);的具体实现
                    awaiter = Task.Delay(this.time).GetAwaiter();
                    if (awaiter.IsCompleted)
                    {
                        goto Label_0077;
                    }
                    this._state = num = 0;
                    this.taskAwaiter1 = awaiter;
                    d__ = this;
                    this._builder.AwaitUnsafeOnCompleted<TaskAwaiter, MyAsyncTest.GetUrlStringAsyncdStateMachine>(ref awaiter, ref d__);
                    return;
            }
            awaiter = this.taskAwaiter1;
            this.taskAwaiter1 = new TaskAwaiter();
            this._state = num = -1;
        Label_0077:
            awaiter.GetResult();
            awaiter = new TaskAwaiter();            //这里是异步方法await http.GetStringAsync(url);的具体实现
            TaskAwaiter<string> awaiter2 = this.http.GetStringAsync(this.url).GetAwaiter();
            if (awaiter2.IsCompleted)
            {
                goto Label_00EA;
            }
            this._state = num = 1;
            this.taskAwaiter2 = awaiter2;
            d__ = this;
            this._builder.AwaitUnsafeOnCompleted<TaskAwaiter<string>, MyAsyncTest.GetUrlStringAsyncdStateMachine>(ref awaiter2, ref d__);
            return;
        Label_00CD:
            awaiter2 = this.taskAwaiter2;
            this.taskAwaiter2 = new TaskAwaiter<string>();
            this._state = num = -1;
        Label_00EA:
            str2 = awaiter2.GetResult();
            awaiter2 = new TaskAwaiter<string>();
            this._str1 = str2;
            str = this._str1;
        }
        catch (Exception exception)
        {
            this._state = -2;
            this._builder.SetException(exception);
            return;
        }
        this._state = -2;
        this._builder.SetResult(str);
    }

    [DebuggerHidden]
    private void SetStateMachine(IAsyncStateMachine stateMachine)
    {
    }

}

明显多个异步等待执行的时候就是在不断调用状态机中的MoveNext()方法。经验来至我们之前分析过的IEumerable,不过今天的这个明显复杂度要高于以前的那个。猜测是如此,我们还是来验证下事实:

在起始方法GetUrlStringAsync第一次启动状态机stateMachine._builder.Start(ref stateMachine);

当然这只是可能性较大的执行流程,但也有awaiter.Iscompleted为true的情况。其他可能的留着大家自己去琢磨吧。

以上就是C#异步的世界(下)的详细内容,更多关于C#异步的资料请关注得得之家其它相关文章!

本文标题为:C#异步的世界(下)