Beispiel #1
0
 public ConfiguredYieldAwaiter(
     YieldAwaitable.YieldAwaiter awaiter,
     bool continueOnCapturedContext
     )
 {
     _awaiter = awaiter;
     _continueOnCapturedContext = continueOnCapturedContext;
 }
Beispiel #2
0
 public void Setup()
 {
     _sc = SynchronizationContext.Current;
     _a  = new YieldAwaitable().GetAwaiter();
 }
Beispiel #3
0
            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);
            }
Beispiel #4
0
            private void MoveNextSingleYield()
            {
                int num = state;
                int result;

                try
                {
                    TaskAwaiter <int>           awaiter;
                    YieldAwaitable.YieldAwaiter awaiter2;
                    if (num != 0)
                    {
                        if (num == 1)
                        {
                            awaiter = u__2;
                            u__2    = default(TaskAwaiter <int>);
                            num     = (state = -1);
                            goto IL_00fb;
                        }
                        awaiter2 = Task.Yield().GetAwaiter();
                        if (!awaiter2.IsCompleted)
                        {
                            num  = (state = 0);
                            u__1 = awaiter2;
                            //CountRecursivelyAsyncd__1 stateMachine = this;
                            t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref this);
                            return;
                        }
                    }
                    else
                    {
                        awaiter2 = u__1;
                        u__1     = default(YieldAwaitable.YieldAwaiter);
                        num      = (state = -1);
                    }
                    awaiter2.GetResult();
                    if (count > 0)
                    {
                        awaiter = CountRecursivelyAsync(count - 1).GetAwaiter();
                        if (!awaiter.IsCompleted)
                        {
                            num  = (state = 1);
                            u__2 = awaiter;
                            //CountRecursivelyAsyncd__1 stateMachine = this;
                            t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref this);
                            return;
                        }
                        goto IL_00fb;
                    }
                    result = count;
                    goto end_IL_0007;
IL_00fb:
                    s__1   = awaiter.GetResult();
                    result = 1 + s__1;
                    end_IL_0007 :;
                }
                catch (Exception exception)
                {
                    state = -2;
                    t__builder.SetException(exception);
                    return;
                }
                state = -2;
                t__builder.SetResult(result);
            }
Beispiel #5
0
 public void Setup()
 {
     a = new YieldAwaitable().GetAwaiter();
 }
        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);
        }