예제 #1
0
        public static Task <T> FromException <T>(Exception exception)
        {
            var source = ValueTaskCompletionSource <T> .Create();

            source.TrySetException(exception);
            return(source.Task);
        }
예제 #2
0
 private void EnsureHasTask()
 {
     if (!_source.HasTask)
     {
         _source = ValueTaskCompletionSource <T> .Create();
     }
 }
예제 #3
0
        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;
            });
        }
예제 #4
0
        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();
        }
예제 #5
0
        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;
            });
        }
예제 #6
0
        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));
        }
예제 #7
0
        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;
            });
        }
예제 #8
0
        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());
        }
예제 #9
0
        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());
        }
예제 #10
0
        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);
        }
예제 #11
0
        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));
        }
예제 #13
0
        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.");
     }
 }
예제 #15
0
        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);
        }
예제 #16
0
        public async Task Complete()
        {
            using var TaskSource = ValueTaskCompletionSource.New();

            var Task = TaskSource.Task;

            Assert.IsFalse(Task.IsCompleted);

            Assert.IsTrue(TaskSource.TrySetResult());

            await Task;
        }
예제 #17
0
        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);
        }
예제 #18
0
        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());
        }
예제 #19
0
        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)
            {
            }
        }
예제 #20
0
        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
        }
예제 #22
0
        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));
        }