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); }
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()); }
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); }
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); }
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; }
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())); }
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); }
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); }
private protected ValueTaskCompletionSource() { builder = AsyncValueTaskMethodBuilder <ValueTask <TResult> > .Create(); completed = new AtomicBoolean(false); }
[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();
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)); }