Example #1
0
        /// <summary>
        /// Handler1的等价代码
        /// </summary>
        /// <param name="vv"></param>
        /// <returns></returns>
        public static Task Handler1No_awiter(int vv)
        {
            Handler1StateMachine h1s = new Handler1StateMachine();

            h1s.vv      = vv;
            h1s.state   = -1;
            h1s.builder = System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Create();
            h1s.builder.Start(ref h1s);
            return(h1s.builder.Task);
        }
Example #2
0
        /// <summary>
        /// 官方的等价翻译
        /// 翻译等价代码的技巧:
        /// 按照原代码的顺序从上往下写,遇到await语句,就转成xxx.GetAwaiter(),并且定义一个对应的TaskAwaiter类型字段
        /// 然后进入IsCompleted判断,每个await语句对应的判断块都类似,不同点:把state设为不同值,这里为方便阅读代码,按照代码顺序递增state的值
        /// 关键方法:builder.AwaitUnsafeOnCompleted;这个方法不会阻塞,当前方法所在线程直接return,去执行其它任务,类库内部帮我们后续再回调到MoveNext
        /// 然后定义一个标签位置,后续代码写在标签之后
        /// </summary>
        public void MoveNext()
        {
            //这里就是配合下面翻译的代码,做的配合工作
            switch (this.state)
            {
            case 0:
                goto block0;

            case 1:
                goto block1;

            default:
                break;
            }
            //翻译等价代码的技巧:
            //按照原代码的顺序从上往下写,遇到await语句,就转成xxx.GetAwaiter(),并且定义一个对应的TaskAwaiter类型字段
            //然后进入IsCompleted判断,每个await语句对应的判断块都类似,不同点:把state设为不同值,这里为方便阅读代码,按照代码顺序递增state的值
            //然后定义一个标签位置,后续代码写在标签之后
            Console.WriteLine("进入Handler1");
            this.awaiterDelay2000 = Task.Delay(2000).GetAwaiter();
            if (!this.awaiterDelay2000.IsCompleted)
            {
                this.state = 0;
                Handler1StateMachine h1s = this;
                this.builder.AwaitUnsafeOnCompleted(ref this.awaiterDelay2000, ref h1s);
                return;
            }
block0:
            this.awaiterDelay2000.GetResult();
            Console.WriteLine("执行完Task.Delay(2000)");
            this.awaiterHandler2 = Program.Handler2(this.vv).GetAwaiter();
            if (!this.awaiterHandler2.IsCompleted)
            {
                this.state = 1;
                Handler1StateMachine h1s = this;
                this.builder.AwaitUnsafeOnCompleted(ref this.awaiterHandler2, ref h1s);
                return;
            }
block1:
            var rt = this.awaiterHandler2.GetResult();

            this.value = rt;
            Console.WriteLine("执行完Handler2");
            this.state = -2;
            this.builder.SetResult();
        }
Example #3
0
        /// <summary>
        /// 简单粗暴翻译
        /// 翻译等价代码的技巧:
        /// 按照原代码的顺序从上往下写,遇到await语句,就转成xxx.GetAwaiter(),并且定义一个对应的TaskAwaiter类型字段
        /// 不做IsCompleted,全部利用builder.AwaitUnsafeOnCompleted方法结束当前方法,释放当前线程
        /// 弊端:遇到Task.FromResult这种代码,就会有点浪费,因为没必要builder.AwaitUnsafeOnCompleted
        /// </summary>
        public void MoveNext2()
        {
            //翻译等价代码的技巧:
            //按照原代码的顺序从上往下写,遇到await语句,就转成xxx.GetAwaiter(),并且定义一个对应的TaskAwaiter类型字段
            //不做IsCompleted,全部利用builder.AwaitUnsafeOnCompleted方法结束当前方法,释放当前线程
            //
            Handler1StateMachine h1s = this;

            switch (this.state)
            {
            case 0:
                Console.WriteLine("进入Handler1");
                this.awaiterDelay2000 = Task.Delay(2000).GetAwaiter();
                this.state            = 1;
                this.builder.AwaitUnsafeOnCompleted(ref this.awaiterDelay2000, ref h1s);
                return;

            case 1:
                this.awaiterDelay2000.GetResult();
                Console.WriteLine("执行完Task.Delay(2000)");
                this.awaiterHandler2 = Program.Handler2(this.vv).GetAwaiter();
                this.state           = 2;
                this.builder.AwaitUnsafeOnCompleted(ref this.awaiterHandler2, ref h1s);
                return;

            case 2:
                var rt = this.awaiterHandler2.GetResult();
                this.value = rt;
                Console.WriteLine("执行完Handler2");
                this.state = 3;
                this.builder.SetResult();
                return;

            default:
                break;
            }
        }