public async Task AwaitOnCompleted_InvokesStateMachineMethods(bool awaitUnsafe)
        {
            AsyncValueTaskMethodBuilder <int> b = ValueTask <int> .CreateAsyncMethodBuilder();

            var ignored = b.Task;

            var callbackCompleted      = new TaskCompletionSource <bool>();
            IAsyncStateMachine foundSm = null;
            var dsm = new DelegateStateMachine
            {
                MoveNextDelegate        = () => callbackCompleted.SetResult(true),
                SetStateMachineDelegate = sm => foundSm = sm
            };

            TaskAwaiter t = Task.CompletedTask.GetAwaiter();

            if (awaitUnsafe)
            {
                b.AwaitUnsafeOnCompleted(ref t, ref dsm);
            }
            else
            {
                b.AwaitOnCompleted(ref t, ref dsm);
            }

            await callbackCompleted.Task;

            Assert.Equal(dsm, foundSm);
        }
        public void AwaitOnCompleted_ForcesTaskCreation(int numAwaits, bool awaitUnsafe)
        {
            AsyncValueTaskMethodBuilder <int> b = ValueTask <int> .CreateAsyncMethodBuilder();

            var dsm             = new DelegateStateMachine();
            TaskAwaiter <int> t = new TaskCompletionSource <int>().Task.GetAwaiter();

            Assert.InRange(numAwaits, 1, int.MaxValue);
            for (int i = 1; i <= numAwaits; i++)
            {
                if (awaitUnsafe)
                {
                    b.AwaitUnsafeOnCompleted(ref t, ref dsm);
                }
                else
                {
                    b.AwaitOnCompleted(ref t, ref dsm);
                }
            }

            b.SetResult(42);

            Assert.True(WrapsTask(b.Task));
            Assert.Equal(42, b.Task.Result);
        }
Exemple #3
0
        public void Start_ExecutionContextChangesInMoveNextDontFlowOut()
        {
            var al = new AsyncLocal<int> { Value = 0 };
            int calls = 0;

            var dsm = new DelegateStateMachine
            {
                MoveNextDelegate = () =>
                {
                    al.Value++;
                    calls++;
                }
            };

            dsm.MoveNext();
            Assert.Equal(1, al.Value);
            Assert.Equal(1, calls);

            dsm.MoveNext();
            Assert.Equal(2, al.Value);
            Assert.Equal(2, calls);

            AsyncValueTaskMethodBuilder<int> b = ValueTask<int>.CreateAsyncMethodBuilder();
            b.Start(ref dsm);
            Assert.Equal(2, al.Value); // change should not be visible
            Assert.Equal(3, calls);

            // Make sure we've not caused the Task to be allocated
            b.SetResult(42);
            ValueTask<int> vt = b.Task;
            Assert.NotSame(vt.AsTask(), vt.AsTask());
        }
        public void SetStateMachine_InvalidArgument_ThrowsException()
        {
            AsyncValueTaskMethodBuilder <int> b = ValueTask <int> .CreateAsyncMethodBuilder();

            Assert.Throws <ArgumentNullException>("stateMachine", () => b.SetStateMachine(null));
            b.SetStateMachine(new DelegateStateMachine());
        }
Exemple #5
0
 public void Start_InvokesMoveNext()
 {
     AsyncValueTaskMethodBuilder<int> b = ValueTask<int>.CreateAsyncMethodBuilder();
     int invokes = 0;
     var dsm = new DelegateStateMachine { MoveNextDelegate = () => invokes++ };
     b.Start(ref dsm);
     Assert.Equal(1, invokes);
 }
Exemple #6
0
 public void SetResult_AfterAccessTask_ValueTaskContainsValue()
 {
     AsyncValueTaskMethodBuilder<int> b = ValueTask<int>.CreateAsyncMethodBuilder();
     ValueTask<int> vt = b.Task;
     b.SetResult(42);
     Assert.True(vt.IsCompletedSuccessfully);
     Assert.Same(vt.AsTask(), vt.AsTask()); // will be safe if completed asynchronously
     Assert.Equal(42, vt.Result);
 }
Exemple #7
0
        private uint                                                      guardedRegionsCounter; // number of entries into try-clause

        private AsyncStateMachine(Transition <TState, AsyncStateMachine <TState> > transition, TState state)
        {
            builder               = AsyncValueTaskMethodBuilder.Create();
            this.transition       = transition;
            State                 = state;
            StateId               = IAsyncStateMachine <TState> .FinalState;
            exception             = null;
            guardedRegionsCounter = 0;
        }
        private uint                        guardedRegionsCounter; //number of entries into try-clause

        private AsyncStateMachine(Transition transition, STATE state)
        {
            builder               = AsyncValueTaskMethodBuilder.Create();
            this.transition       = transition;
            State                 = state;
            StateId               = FINAL_STATE;
            exception             = null;
            guardedRegionsCounter = 0;
        }
Exemple #9
0
 public void SetException_OperationCanceledException_CancelsTask()
 {
     AsyncValueTaskMethodBuilder<int> b = ValueTask<int>.CreateAsyncMethodBuilder();
     var e = new OperationCanceledException();
     ValueTask<int> vt = b.Task;
     b.SetException(e);
     Assert.True(vt.IsCanceled);
     Assert.Same(e, Assert.Throws<OperationCanceledException>(() => vt.GetAwaiter().GetResult()));
 }
Exemple #10
0
 public void SetException_AfterAccessTask_FaultsTask()
 {
     AsyncValueTaskMethodBuilder<int> b = ValueTask<int>.CreateAsyncMethodBuilder();
     var e = new FormatException();
     ValueTask<int> vt = b.Task;
     b.SetException(e);
     Assert.True(vt.IsFaulted);
     Assert.Same(e, Assert.Throws<FormatException>(() => vt.GetAwaiter().GetResult()));
 }
        public void SetResult_AfterAccessTask_ValueTaskContainsValue()
        {
            AsyncValueTaskMethodBuilder <int> b = default;
            ValueTask <int> vt = b.Task;

            b.SetResult(42);
            Assert.True(vt.IsCompletedSuccessfully);
            Assert.True(WrapsTask(vt));
            Assert.Equal(42, vt.Result);
        }
Exemple #12
0
        private AsyncStateMachine(Transition <TState, AsyncStateMachine <TState, TResult> > transition, TState state)
        {
            builder = AsyncValueTaskMethodBuilder <TResult> .Create();

            StateId               = IAsyncStateMachine <TState> .FinalState;
            State                 = state;
            this.transition       = transition;
            guardedRegionsCounter = 0;
            exception             = null;
            result                = default;
        }
        public void SetResult_BeforeAccessTask_ValueTaskContainsValue()
        {
            AsyncValueTaskMethodBuilder <int> b = ValueTask <int> .CreateAsyncMethodBuilder();

            b.SetResult(42);
            ValueTask <int> vt = b.Task;

            Assert.True(vt.IsCompletedSuccessfully);
            Assert.False(WrapsTask(vt));
            Assert.Equal(42, vt.Result);
        }
        // RESULTS
        // M1Async and M2Async : exact same assembly code
        // M1AsyncAsyncA, M1AsyncAsyncB and M2AsyncASync : exact same assembly code
        //  (heavy usage of the state machine)
        // so the diff is in the state machine
        //
        // M1AsyncAsyncA
        //  ValueTask<int> valueTask = (c.FAsync != null) ? c.FAsync() : default(ValueTask<int>);
        //  awaiter = valueTask.GetAwaiter();
        //
        // M2AsyncAsync
        //  Func<ValueTask<int>> fAsync = c.FAsync;
        //  ValueTask<int> valueTask = (fAsync != null) ? fAsync() : default(ValueTask<int>);
        //  awaiter = valueTask.GetAwaiter();
        //
        // M1AsyncAsyncB
        //  if (c.FAsync == null) { result = 0; done; }
        //  awaiter = c.FAsync().GetAwaiter();
        //
        // assembly level, M1AsyncAsyncA and M2AsyncAsync are practically equivalent
        // assembly level, M1AsyncAsyncB is marginally simpler

        private ValueTask <int> M1AsyncAsyncA__generated()
        {
            M1AsyncAsyncA__d__5 stateMachine = default(M1AsyncAsyncA__d__5);

            stateMachine.__4__this    = this;
            stateMachine.__t__builder = AsyncValueTaskMethodBuilder <int> .Create();

            stateMachine.__1__state = -1;

            AsyncValueTaskMethodBuilder <int> __t__builder = stateMachine.__t__builder;

            __t__builder.Start(ref stateMachine);

            return(stateMachine.__t__builder.Task);
        }
Exemple #15
0
        private protected ValueTaskCompletionSource()
        {
            builder = AsyncValueTaskMethodBuilder <ValueTask <TResult> > .Create();

            completed = new AtomicBoolean(false);
        }
Exemple #16
0
 [EditorBrowsable(EditorBrowsableState.Never)] // intended only for compiler consumption
 public static AsyncValueTaskMethodBuilder <TResult> CreateAsyncMethodBuilder()
 {
     return(AsyncValueTaskMethodBuilder <TResult> .Create());
 }
        public void Create_ReturnsDefaultInstance()
        {
            AsyncValueTaskMethodBuilder <int> b = ValueTask <int> .CreateAsyncMethodBuilder();

            Assert.Equal(default(AsyncValueTaskMethodBuilder <int>), b); // implementation detail being verified
        }
        [EditorBrowsable(EditorBrowsableState.Never)] // intended only for compiler consumption
#endif
        public static AsyncValueTaskMethodBuilder <TResult> CreateAsyncMethodBuilder() => AsyncValueTaskMethodBuilder <TResult> .Create();
Exemple #19
0
        public void NonGeneric_Create_ReturnsDefaultInstance()
        {
            AsyncValueTaskMethodBuilder b = default;

            Assert.Equal(default, b); // implementation detail being verified
        public void SetStateMachine_InvalidArgument_ThrowsException()
        {
            AsyncValueTaskMethodBuilder <int> b = default;

            AssertExtensions.Throws <ArgumentNullException>("stateMachine", () => b.SetStateMachine(null));
        }