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(); }
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"); }
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(); }
public void TestSetExceptionTwice_ThrowException() { var sut = new FastTaskCompletionSource <string>(); Action action = () => sut.SetException(new ArgumentNullException("xxx")); action.Should().NotThrow(); action.Should().Throw <InvalidOperationException>(); }
public void TestSetCanceledTwice_ThrowException() { var sut = new FastTaskCompletionSource <string>(); Action action = () => sut.SetCanceled(); action.Should().NotThrow(); action.Should().Throw <InvalidOperationException>(); }
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); }
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"); }
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(); }
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(); }
/// <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); }