public void MoveNext()
        {
            int result;
            try
            {
                Action continuation;
                TaskAwaiter localTaskAwaiter;
                YieldAwaitable.YieldAwaiter[] yieldAwaiterArray;
                bool doFinallyBodies = true;
                switch (this.state)
                {
                    case 1:
                        break;
                    case 2:
                        goto Await2CompletedTrampoline1;
                    case 3:
                        goto Await3Completed;
                    default:
                        if (this.state != -1)
                        {
                            Console.WriteLine("Bit tired. Taking a rest...");
                            localTaskAwaiter = Task.Delay(1000).GetAwaiter();
                            if (localTaskAwaiter.IsCompleted)
                            {
                                goto Await1Completed;
                            }
                            this.state = 1;
                            TaskAwaiter[] taskAwaiterArray = { localTaskAwaiter };
                            this.awaiter = taskAwaiterArray;
                            continuation = this.MoveNextDelegate;
                            if (continuation == null)
                            {
                                // Force the task to be created before there's any possible race.
                                Task<int> task = this.builder.Task;

                                continuation = MoveNext;
                                // Careful here: set the continuation field in the boxed copy.
                                ((IStateMachine)continuation.Target).SetMoveNextDelegate(continuation);
                            }
                            taskAwaiterArray[0].OnCompleted(continuation);
                            doFinallyBodies = false;
                        }
                        return;
                }
                // For state == 1, i.e. continuing from first await
                localTaskAwaiter = ((TaskAwaiter[]) this.awaiter)[0];
                this.awaiter = null;
                this.state = 0;
              Await1Completed:
                localTaskAwaiter.GetResult();
                localTaskAwaiter = default(TaskAwaiter);
                this.total =  0;
                this.rng = new Random();
                this.outerLogFrame = new LogFrame("Outside loop");
              // We can't jump into the middle of a try block...
              Await2CompletedTrampoline1:
                try
                {
                    int localState = this.state;
                    bool fakeTrampoline2 = false;
                    if (localState == 2)
                    {
                        // Can't actually do this...
                        // goto Await2CompletedTrampoline2;
                        // So let's fake it...
                        fakeTrampoline2 = true;
                    }
                    if (!fakeTrampoline2)
                    {
                        this.i = 0;
                    }
                    while (fakeTrampoline2 || i < this.count)
                    {
                        if (!fakeTrampoline2)
                        {
                            this.innerLogFrame = new LogFrame("Inside loop");
                        }
                        fakeTrampoline2 = false;
                      // We still can't jump into the middle of a try block...
                      // The C# compiler can generate code to jump here, but it's not
                      // valid C#...
                      // Await2CompletedTrampoline2:
                        try
                        {
                            int totalBefore = 0; // Initialization isn't present in IL, but I believe it's implicit...
                            TaskAwaiter<int> localTaskInt32Awaiter;
                            localState = this.state;
                            // Can only be because state = 0, i.e. we've gone back to the top of the loop
                            if (localState != 2)
                            {
                                localTaskInt32Awaiter = GeneratedProgram.WaitAndReturnRandomNumber(this.rng).GetAwaiter();
                                if (!localTaskInt32Awaiter.IsCompleted)
                                {
                                    totalBefore = total;
                                    this.stack = totalBefore; // Unclear why we need this...
                                    this.state = 2;
                                    TaskAwaiter<int>[] taskInt32AwaiterArray = { localTaskInt32Awaiter };
                                    this.awaiter = taskInt32AwaiterArray;

                                    continuation = this.MoveNextDelegate;
                                    if (continuation == null)
                                    {
                                        // Force the task to be created before there's any possible race.
                                        Task<int> task = this.builder.Task;

                                        continuation = MoveNext;
                                        // Careful here: set the continuation field in the boxed copy.
                                        ((IStateMachine)continuation.Target).SetMoveNextDelegate(continuation);
                                    }
                                    taskInt32AwaiterArray[0].OnCompleted(continuation);
                                    doFinallyBodies = false;
                                    return;
                                }
                            }
                            else
                            {
                                // Trampolined in from the continuation in state 2
                                totalBefore = (int)this.stack;
                                this.stack = null;
                                localTaskInt32Awaiter = ((TaskAwaiter<int>[])this.awaiter)[0];
                                this.awaiter = null;
                                this.state = 0;
                            }
                            int localTaskInt32Result = localTaskInt32Awaiter.GetResult();
                            localTaskInt32Awaiter = default(TaskAwaiter<int>);
                            totalBefore += localTaskInt32Result;
                            this.total = totalBefore;
                        }
                        finally
                        {
                            if (doFinallyBodies && this.innerLogFrame != null)
                            {
                                this.innerLogFrame.Dispose();
                            }
                        }
                        this.i++;
                    }
                }
                finally
                {
                    if (doFinallyBodies && this.outerLogFrame != null)
                    {
                        this.outerLogFrame.Dispose();
                    }
                }
                Console.WriteLine("Finished looping. Will just yield for fun.");
                YieldAwaitable.YieldAwaiter localYieldAwaiter = Task.Yield().GetAwaiter();
                if (localYieldAwaiter.IsCompleted)
                {
                    goto Await3CompletedImmediately;
                }
                this.state = 3;
                yieldAwaiterArray = new YieldAwaitable.YieldAwaiter[] { localYieldAwaiter };
                this.awaiter = yieldAwaiterArray;
                
                continuation = this.MoveNextDelegate;
                if (continuation == null)
                {
                    // Force the task to be created before there's any possible race.
                    Task<int> task = this.builder.Task;

                    continuation = MoveNext;
                    // Careful here: set the continuation field in the boxed copy.
                    ((IStateMachine)continuation.Target).SetMoveNextDelegate(continuation);
                }
                yieldAwaiterArray[0].OnCompleted(continuation);
                doFinallyBodies = false;
                return;
              Await3Completed:
                 localYieldAwaiter = ((YieldAwaitable.YieldAwaiter[]) this.awaiter)[0];
                 this.awaiter = null;
                 this.state = 0;
              Await3CompletedImmediately:
                 localYieldAwaiter.GetResult();
                 localYieldAwaiter = default(YieldAwaitable.YieldAwaiter);
                result = this.total;
            }
            catch (Exception e)
            {
                this.state = -1;
                this.builder.SetException(e);
                return;
            }
            this.state = -1;
            this.builder.SetResult(result);
        }
Example #2
0
		public void Setup ()
		{
			a = new YieldAwaitable ().GetAwaiter ();
		}
            void IAsyncStateMachine.MoveNext()
            {
                int result = default(int);
                try
                {
                    bool doFinallyBodies = true;
                    switch (state)
                    {
                        case -3:
                            goto Done;
                        case 0:
                            goto FirstAwaitContinuation;
                        case 1:
                            goto SecondAwaitContinuation;
                    }
                    // Default case - first call (state is -1)
                    total = 0;
                    iterator = text.GetEnumerator();

                // We really want to jump straight to FirstAwaitRealContinuation, but we can't
                // goto a label inside a try block...
                FirstAwaitContinuation:
                    // foreach loop
                    try
                    {
                        // for/foreach loops typically have the condition at the end of the generated code.
                        // We want to go there *unless* we're trying to reach the first continuation.
                        if (state != 0)
                        {
                            goto LoopCondition;
                        }
                        goto FirstAwaitRealContinuation;
                    LoopBody:
                        ch = iterator.Current;
                        unicode = ch;
                        TaskAwaiter localTaskAwaiter = Task.Delay(unicode).GetAwaiter();
                        if (localTaskAwaiter.IsCompleted)
                        {
                            goto FirstAwaitCompletion;
                        }
                        state = 0;
                        taskAwaiter = localTaskAwaiter;
                        builder.AwaitUnsafeOnCompleted(ref localTaskAwaiter, ref this);
                        doFinallyBodies = false;
                        return;
                    FirstAwaitRealContinuation:
                        localTaskAwaiter = taskAwaiter;
                        taskAwaiter = default(TaskAwaiter);
                        state = -1;
                    FirstAwaitCompletion:
                        localTaskAwaiter.GetResult();
                        localTaskAwaiter = default(TaskAwaiter);
                        total += unicode;
                    LoopCondition:
                        if (iterator.MoveNext())
                        {
                            goto LoopBody;
                        }
                    }
                    finally
                    {
                        if (doFinallyBodies && iterator != null)
                        {
                            iterator.Dispose();
                        }
                    }

                    // After the loop
                    YieldAwaitable.YieldAwaiter localYieldAwaiter = Task.Yield().GetAwaiter();
                    if (localYieldAwaiter.IsCompleted)
                    {
                        goto SecondAwaitCompletion;
                    }
                    state = 1;
                    yieldAwaiter = localYieldAwaiter;
                    builder.AwaitUnsafeOnCompleted(ref localYieldAwaiter, ref this);
                    doFinallyBodies = false;
                    return;

                SecondAwaitContinuation:
                    localYieldAwaiter = yieldAwaiter;
                    yieldAwaiter = default(YieldAwaitable.YieldAwaiter);
                    state = -1;
                    SecondAwaitCompletion:
                    localYieldAwaiter.GetResult();
                    localYieldAwaiter = default(YieldAwaitable.YieldAwaiter);
                    result = total;
                }
                catch (Exception ex)
                {
                    state = -2;
                    builder.SetException(ex);
                    return;
                }
                Done:
                state = -2;
                builder.SetResult(result);
            }
Example #4
0
		public void Setup ()
		{
			sc = SynchronizationContext.Current;
			a = new YieldAwaitable ().GetAwaiter ();
		}