public static Task <T> FromException <T>(Exception exception) { var source = ValueTaskCompletionSource <T> .Create(); source.TrySetException(exception); return(source.Task); }
private void EnsureHasTask() { if (!_source.HasTask) { _source = ValueTaskCompletionSource <T> .Create(); } }
public async Task PartiallyCompletedCanceled2WhenAllTest() { var taskSources = new ValueTaskCompletionSource <int> [3]; for (var i = 0; i < taskSources.Count(); i++) { taskSources[i] = ValueTaskCompletionSource <int> .Create(); } taskSources[1].SetCanceled(); var task = taskSources.Select(p => p.Task).WhenAll(preserveOrder: true); Assert.IsFalse(task.IsCompleted); // Complete the tasks in non-sort order and wait some time in between taskSources[2].SetResult(2); await Task.Delay(10); taskSources[0].SetResult(0); await Task.Delay(20); // Wait some time to allow the continuations to execute Assert.IsTrue(task.IsCompleted); Assert.IsTrue(task.IsCanceled); await Assert.ThrowsExceptionAsync <TaskCanceledException>(async() => { await task; }); }
public async Task WhenAllNonGenericTest() { var taskSources = new ValueTaskCompletionSource[3]; for (var i = 0; i < taskSources.Count(); i++) { taskSources[i] = ValueTaskCompletionSource.Create(); } var task = taskSources.Select(p => p.Task).WhenAll(); Assert.IsFalse(task.IsCompleted); // Complete the tasks in non-sort order and wait some time in between taskSources[1].SetResult(); await Task.Delay(10); taskSources[2].SetResult(); await Task.Delay(10); taskSources[0].SetResult(); Assert.IsTrue(task.IsCompletedSuccessfully); task.GetAwaiter().GetResult(); }
public async Task PartiallyCompletedExceptionNonPreserveOrder2WhenAllTest() { var taskSources = new ValueTaskCompletionSource <int> [3]; for (var i = 0; i < taskSources.Count(); i++) { taskSources[i] = ValueTaskCompletionSource <int> .Create(); } taskSources[1].SetException(new CustomException()); var task = taskSources.Select(p => p.Task).WhenAll(preserveOrder: false); Assert.IsFalse(task.IsCompleted); // Complete the tasks in non-sort order and wait some time in between taskSources[2].SetResult(2); await Task.Delay(10); taskSources[0].SetResult(0); Assert.IsTrue(task.IsCompleted); Assert.IsTrue(task.IsFaulted); await Assert.ThrowsExceptionAsync <CustomException>(async() => { await task; }); }
public async Task WhenAllTest() { var taskSources = new ValueTaskCompletionSource <int> [3]; for (var i = 0; i < taskSources.Count(); i++) { taskSources[i] = ValueTaskCompletionSource <int> .Create(); } var task = taskSources.Select(p => p.Task).WhenAll(preserveOrder: true); Assert.IsFalse(task.IsCompleted); // Complete the tasks in non-sort order and wait some time in between taskSources[1].SetResult(1); await Task.Delay(10); taskSources[2].SetResult(2); await Task.Delay(10); taskSources[0].SetResult(0); await Task.Delay(20); // Wait some time to allow the continuations to execute Assert.IsTrue(task.IsCompletedSuccessfully); var result = task.GetAwaiter().GetResult(); // We are allowed only once to get the result. Assert.IsNotNull(result); Assert.IsTrue(new[] { 0, 1, 2 }.SequenceEqual(result)); }
public async Task PartiallyCompletedCanceledNonGeneric2WhenAllTest() { var taskSources = new ValueTaskCompletionSource[3]; for (var i = 0; i < taskSources.Count(); i++) { taskSources[i] = ValueTaskCompletionSource.Create(); } taskSources[1].SetCanceled(); var task = taskSources.Select(p => p.Task).WhenAll(); Assert.IsFalse(task.IsCompleted); // Complete the tasks in non-sort order and wait some time in between taskSources[2].SetResult(); await Task.Delay(10); taskSources[0].SetResult(); Assert.IsTrue(task.IsCompleted); Assert.IsTrue(task.IsCanceled); await Assert.ThrowsExceptionAsync <TaskCanceledException>(async() => { await task; }); }
public async Task MultipleAsyncIndexOutOfOrder() { var FirstSource = ValueTaskCompletionSource.New <int>(); var SecondSource = ValueTaskCompletionSource.New <int>(); await using var Enumerator = new[] { FirstSource.Task, SecondSource.Task }.InterleaveIndex().GetAsyncEnumerator(); var Waiter = Enumerator.MoveNextAsync(); Assert.IsFalse(Waiter.IsCompleted); SecondSource.TrySetResult(108); Assert.IsTrue(await Waiter); Assert.IsTrue(Enumerator.Current.result.IsCompleted); Assert.AreEqual(SecondSource.Task.Result, Enumerator.Current.result.Result); Assert.AreEqual(1, Enumerator.Current.index); Waiter = Enumerator.MoveNextAsync(); Assert.IsFalse(Waiter.IsCompleted); FirstSource.TrySetResult(42); Assert.IsTrue(await Waiter); Assert.IsTrue(Enumerator.Current.result.IsCompleted); Assert.AreEqual(FirstSource.Task.Result, Enumerator.Current.result.Result); Assert.AreEqual(0, Enumerator.Current.index); Assert.IsFalse(await Enumerator.MoveNextAsync()); }
public async Task ExceptionAsync() { var FirstSource = ValueTaskCompletionSource.New <int>(); await using var Enumerator = new[] { FirstSource.Task }.Interleave().GetAsyncEnumerator(); var Waiter = Enumerator.MoveNextAsync(); Assert.IsFalse(Waiter.IsCompleted); FirstSource.TrySetException(new ApplicationException("Test")); Assert.IsTrue(await Waiter); try { await Enumerator.Current; Assert.Fail("Did not throw"); } catch (ApplicationException) { } Assert.IsFalse(await Enumerator.MoveNextAsync()); }
static async Task ValueTaskCompletionSourceExampleAsync() { var vtcs = new ValueTaskCompletionSource <int>(false); var are = new AutoResetEvent(false); var t1 = Task.Run(() => { int v = 0; while (true) { Thread.Sleep(1_000); // attempts to execute await t before set result vtcs.SetResult(v++); are.WaitOne(); } }); var t2 = Task.Run(async() => { while (true) { ValueTask <int> t = vtcs.Task; var result = await t.ConfigureAwait(false); Console.WriteLine($"{result}"); are.Set(); } }); await Task.WhenAll(t1, t2).ConfigureAwait(false); }
public Task GetTask(short token) { lock (this) { CheckTokenInsideLock(token); if (_task != null) { } else if (_exception is OperationCanceledException) { _task = TaskUtils.TaskFactory <T> .Canceled; } else if (_exception != null) { _task = TaskUtils.FromException <T>(_exception); } else if (_isComplete) { _task = typeof(T) == typeof(Nothing) ? TaskUtils.CompletedTask : TaskUtils.TaskFactory <T> .FromResult(_result); } else { _source = ValueTaskCompletionSource <T> .Create(); _task = _source.Task; } return(_task); } }
public void DefaultInstanceBehavior() { ValueTaskCompletionSource <int> source = default; Assert.True(source.IsNull); Assert.False(source.IsOptimized); Assert.False(source.TrySetResult(42)); }
public void FallbackTask(bool shouldFault) { Counters.Reset(); var source = ValueTaskCompletionSource <int> .CreateFallback(); Assert.Equal(1, Counters.TaskAllocated.Value); Assert.False(source.IsOptimized); Verify(source, shouldFault); }
/// <summary> /// Transitions the underlying <see cref="ValueTask{TResult}"/> object /// into the <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state, /// depending on the type of exception. /// </summary> /// <typeparam name="TResult"> /// The type of the result value associated with the <see cref="ValueTaskCompletionSource{TResult}"/>. /// </typeparam> /// <param name="taskCompletionSource">The task completion source.</param> /// <param name="exception">The exception to bind to the <see cref="ValueTask{TResult}"/>.</param> /// <exception cref="ArgumentNullException"> /// Thrown if any of <paramref name="taskCompletionSource"/> or <paramref name="exception"/> is <c>null</c>. /// </exception> /// <exception cref="InvalidOperationException"> /// The <see cref="ValueTask{TResult}"/> is already in one of the three final states: /// <see cref="TaskStatus.RanToCompletion"/>, <see cref="TaskStatus.Faulted"/>, /// or <see cref="TaskStatus.Canceled"/>. /// </exception> public static void SetExceptionOrCanceled <TResult>( this ValueTaskCompletionSource <TResult> taskCompletionSource, Exception exception) { if (!TrySetExceptionOrCanceled(taskCompletionSource, exception)) { throw new InvalidOperationException( "The underlying Task<TResult> is already in one of the three final states:" + " RanToCompletion, Faulted, or Canceled."); } }
public void OptimizedTask(bool shouldFault) { Counters.Reset(); var source = ValueTaskCompletionSource <int> .CreateOptimized(); #if DEBUG Assert.Equal(1, Counters.TaskAllocated.Value); #endif Assert.True(source.IsOptimized); Verify(source, shouldFault); }
public async Task Complete() { using var TaskSource = ValueTaskCompletionSource.New(); var Task = TaskSource.Task; Assert.IsFalse(Task.IsCompleted); Assert.IsTrue(TaskSource.TrySetResult()); await Task; }
public async Task CompleteResult() { using var TaskSource = ValueTaskCompletionSource.New <int>(); var Task = TaskSource.Task; Assert.IsFalse(Task.IsCompleted); Assert.IsTrue(TaskSource.TrySetResult(123)); var Result = await Task; Assert.AreEqual(123, Result); }
public async Task SingleAsync() { var FirstSource = ValueTaskCompletionSource.New <int>(); await using var Enumerator = new[] { FirstSource.Task }.Interleave().GetAsyncEnumerator(); var Waiter = Enumerator.MoveNextAsync(); Assert.IsFalse(Waiter.IsCompleted); FirstSource.TrySetResult(42); Assert.IsTrue(await Waiter); Assert.IsTrue(Enumerator.Current.IsCompleted); Assert.AreEqual(FirstSource.Task.Result, Enumerator.Current.Result); Assert.IsFalse(await Enumerator.MoveNextAsync()); }
public async Task ExceptionResult() { using var TaskSource = ValueTaskCompletionSource.New <int>(); var Task = TaskSource.Task; Assert.IsFalse(Task.IsCompleted); Assert.IsTrue(TaskSource.TrySetException(new ApplicationException())); try { var Result = await Task; Assert.Fail("Should not reach here"); } catch (ApplicationException) { } }
public async Task CancelEnumerableWith() { var FirstSource = ValueTaskCompletionSource.New <int>(); var CancelSource = new CancellationTokenSource(); await using var Enumerator = new[] { FirstSource.Task }.Interleave().WithCancellation(CancelSource.Token).GetAsyncEnumerator(); var Waiter = Enumerator.MoveNextAsync(); CancelSource.Cancel(); try { await Waiter; Assert.Fail("Did not cancel"); } catch (OperationCanceledException) { } }
private void Verify(ValueTaskCompletionSource <int> source, bool shouldFault) { var task = source.Task; Assert.False(task.IsCompleted); Assert.False(task.Status == TaskStatus.RanToCompletion); if (shouldFault) { Assert.True(source.TrySetException(new FormatException())); Assert.False(source.TrySetResult(42)); Assert.False(source.TrySetException(new FormatException())); for (int i = 0; i < 2; i++) // can check multiple times { Assert.True(task.IsFaulted); Assert.True(task.IsCompleted); Assert.False(task.Status == TaskStatus.RanToCompletion); var ex = Assert.Throws <AggregateException>(() => task.Result); Assert.IsType <FormatException>(ex.InnerException); } } else { Assert.True(source.TrySetResult(42)); Assert.False(source.TrySetResult(42)); Assert.False(source.TrySetException(new FormatException())); for (int i = 0; i < 2; i++) // can check multiple times { Assert.False(task.IsFaulted); Assert.True(task.IsCompleted); Assert.True(task.Status == TaskStatus.RanToCompletion); Assert.Equal(42, task.Result); } } Assert.False(source.IsNull); // still good }
public static ValueTask WaitForExitAsync(this Process process, CancellationToken cancellation = default) { var tcs = ValueTaskCompletionSource.Create(); #pragma warning disable CA1062 process.EnableRaisingEvents = true; #pragma warning restore CA1062 process.Exited += (s, o) => tcs.TrySetResult(); // This is needed in order to prevent a race condition when the process exits before we can setup our event handler. process.Refresh(); if (process.HasExited) { tcs.TrySetResult(); } if (cancellation.CanBeCanceled) { cancellation.Register(() => tcs.TrySetCanceled()); } return(tcs.Task); }
/// <summary> /// Attempts to transition the underlying <see cref="ValueTask{TResult}"/> object /// into the <see cref="TaskStatus.Faulted"/> or <see cref="TaskStatus.Canceled"/> state, /// depending on the type of exception. /// </summary> /// <typeparam name="TResult"> /// The type of the result value associated with the <see cref="ValueTaskCompletionSource{TResult}"/>. /// </typeparam> /// <param name="taskCompletionSource">The task completion source.</param> /// <param name="exception">The exception to bind to the <see cref="ValueTask{TResult}"/>.</param> /// <returns>True if the operation was succesful, false otherwise.</returns> /// <exception cref="ArgumentNullException"> /// Thrown if any of <paramref name="taskCompletionSource"/> or <paramref name="exception"/> is <c>null</c>. /// </exception> public static bool TrySetExceptionOrCanceled <TResult>( this ValueTaskCompletionSource <TResult> taskCompletionSource, Exception exception) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } if (exception is OperationCanceledException operationCanceledException) { var cancellationToken = operationCanceledException.CancellationToken; if (cancellationToken != default) { return(taskCompletionSource.TrySetCanceled(cancellationToken)); } return(taskCompletionSource.TrySetCanceled()); } return(taskCompletionSource.TrySetException(exception)); }