Ejemplo n.º 1
0
        public void TestSetResultAsynchronously_AndAwaitDirectly1()
        {
            var scheduler = new TestScheduler();
            var sut       = new FastTaskCompletionSource <string>();

            var threadId = Thread.CurrentThread.ManagedThreadId;

            var task = scheduler
                       .Run(async ct =>
            {
                Thread.CurrentThread.ManagedThreadId.Should().Be(threadId);
                var r = await sut;
                Thread.CurrentThread.ManagedThreadId.Should().Be(threadId);
                return(r);
            }, CancellationToken.None);

            task.IsCompleted.Should().BeFalse();
            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeFalse();
            sut.SetResult("1234");

            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.RanToCompletion);
            task.Result.Should().BeEquivalentTo("1234");

            scheduler.Stop();
        }
Ejemplo n.º 2
0
        public void TestSetExceptionSynchronously_UsingExceptionDispatchInfo2()
        {
            var sut = new FastTaskCompletionSource <string>();

            // The task is created BEFORE the task being canceled
            var task = sut.Task;

            task.IsCompleted.Should().BeFalse();

            try
            {
                throw new ArgumentNullException("xxx");
            }
            catch (ArgumentNullException ex)
            {
                sut.SetException(ExceptionDispatchInfo.Capture(ex));
            }

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.Faulted);
            task.Exception.Should().NotBeNull();
            var aggregateException = task.Exception;

            aggregateException.InnerExceptions.Should().HaveCount(1);
            var argException = aggregateException.InnerException;

            argException.Should().BeOfType <ArgumentNullException>();
            argException.TargetSite.Name.Should().BeEquivalentTo(nameof(TestSetExceptionSynchronously_UsingExceptionDispatchInfo2), "original context is lost");
        }
Ejemplo n.º 3
0
        public void TestSetCanceledAsynchronously()
        {
            var scheduler = new TestScheduler();
            var sut       = new FastTaskCompletionSource <string>();

            var threadId = Thread.CurrentThread.ManagedThreadId;

            var task = scheduler
                       .Run(async ct =>
            {
                Thread.CurrentThread.ManagedThreadId.Should().Be(threadId);
                await sut.Task;
                throw new Exception("should not reach here");
            }, CancellationToken.None);

            task.IsCompleted.Should().BeFalse();
            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeFalse();

            sut.SetCanceled();

            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.Canceled);

            scheduler.Stop();
        }
Ejemplo n.º 4
0
        public void TestSetExceptionTwice_ThrowException()
        {
            var sut = new FastTaskCompletionSource <string>();

            Action action = () => sut.SetException(new ArgumentNullException("xxx"));

            action.Should().NotThrow();
            action.Should().Throw <InvalidOperationException>();
        }
Ejemplo n.º 5
0
        public void TestSetCanceledTwice_ThrowException()
        {
            var sut = new FastTaskCompletionSource <string>();

            Action action = () => sut.SetCanceled();

            action.Should().NotThrow();
            action.Should().Throw <InvalidOperationException>();
        }
Ejemplo n.º 6
0
        public void TestSetCanceledSynchronously1()
        {
            var sut = new FastTaskCompletionSource <string>();

            sut.SetCanceled();

            // The task is created AFTER the task being canceled
            var task = sut.Task;

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.Canceled);
        }
Ejemplo n.º 7
0
        public void TestSetResultSynchronously1()
        {
            var sut = new FastTaskCompletionSource <string>();

            sut.SetResult("1234");

            // The task is created AFTER the result being set
            var task = sut.Task;

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.RanToCompletion);
            task.Result.Should().BeEquivalentTo("1234");
        }
Ejemplo n.º 8
0
        public void TestSetExceptionAsynchronously()
        {
            var scheduler = new TestScheduler();
            var sut       = new FastTaskCompletionSource <string>();

            var threadId = Thread.CurrentThread.ManagedThreadId;

            var task = scheduler
                       .Run(async ct =>
            {
                Thread.CurrentThread.ManagedThreadId.Should().Be(threadId);
                await sut.Task;
                throw new Exception("should not reach here");
            }, CancellationToken.None);

            task.IsCompleted.Should().BeFalse();
            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeFalse();

            try
            {
                throw new ArgumentNullException("xxx");
            }
            catch (ArgumentNullException ex)
            {
                sut.SetException(ex);
            }

            scheduler.AdvanceBy(5);

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.Faulted);
            task.Exception.Should().NotBeNull();
            var aggregateException = task.Exception;

            aggregateException.InnerExceptions.Should().HaveCount(1);
            var argException = aggregateException.InnerException;

            argException.Should().BeOfType <ArgumentNullException>();
            argException.TargetSite.Name.Should().BeEquivalentTo(nameof(TestSetExceptionAsynchronously), "original context is lost");

            scheduler.Stop();
        }
Ejemplo n.º 9
0
        public void TestSetExceptionSynchronously_WithTaskCanceledException2()
        {
            var sut = new FastTaskCompletionSource <string>();

            try
            {
                throw new TaskCanceledException("xxx");
            }
            catch (TaskCanceledException ex)
            {
                sut.SetException(ex);
            }

            // The task is created AFTER the task being canceled
            var task = sut.Task;

            task.IsCompleted.Should().BeTrue();
            task.Status.Should().Be(TaskStatus.Canceled);
            task.Exception.Should().BeNull();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Awaits a task execution on the specified scheduler, providing the result.
        /// </summary>
        /// <returns>A task that will provide the result of the execution.</returns>
        public static Task <T> Run <T>(this IScheduler source, Func <CancellationToken, Task <T> > taskBuilder, CancellationToken cancellationToken)
        {
            var completion = new FastTaskCompletionSource <T>();

            var disposable = new SingleAssignmentDisposable();
            var ctr        = default(CancellationTokenRegistration);

            if (cancellationToken.CanBeCanceled)
            {
                ctr = cancellationToken.Register(() =>
                {
                    completion.TrySetCanceled();
                    disposable.Dispose();
                });
            }

            disposable.Disposable = source.Schedule(
                async() =>
            {
                try
                {
                    var result = await taskBuilder(cancellationToken);
                    completion.TrySetResult(result);
                }
                catch (Exception e)
                {
                    completion.TrySetException(e);
                }
                finally
                {
                    ctr.Dispose();
                }
            }
                );

            return(completion.Task);
        }