public async Task AsyncExceptionIsPropagatedToGetNextCall() { TaskCompletionSource <int> tcs = new TaskCompletionSource <int>(); IAsyncEnumerator <int> enumerator = AwaitAndYieldItem(); AsyncItem <int> itemTask = enumerator.GetNextAsync(); tcs.SetException(new Exception("The punch has been spiked")); Func <Task <Optional <int> > > awaitFaultyItemAct = async() => await itemTask; awaitFaultyItemAct.ShouldThrow <Exception>(); Optional <int> itemAfterException = await enumerator.GetNextAsync().WithSyncContext(); itemAfterException.HasValue.Should().BeFalse(); async IAsyncEnumerator <int> AwaitAndYieldItem() { int awaitedItem = await tcs.Task.ConfigureAwait(false); await AsyncYield.Item(awaitedItem); return(await AsyncYield.Break <int>()); } }
public async Task TrueAwaitsAreSupported() { const int expectedValue = 42; TaskCompletionSource <int> tcs = new TaskCompletionSource <int>(); IAsyncEnumerator <int> enumerator = AwaitTaskThenYieldItem(); AsyncItem <int> nextItemTask = enumerator.GetNextAsync(); nextItemTask.IsCompleted.Should().BeFalse(); tcs.SetResult(expectedValue); Optional <int> yieldedItem = await nextItemTask.WithSyncContext(); yieldedItem.HasValue.Should().BeTrue(); yieldedItem.Value.Should().Be(expectedValue); async IAsyncEnumerator <int> AwaitTaskThenYieldItem() { int awaitedValue = await tcs.Task.ConfigureAwait(false); await AsyncYield.Item(awaitedValue); return(await AsyncYield.Break <int>()); } }
public static Task <T> GetNextAsync <T>(this IAsyncEnumerator <T> @this, CancellationToken token) { return(@this.GetNextAsync().AsTask().ContinueWith <Task <T> >( continuationFunction: ante => ante, cancellationToken: token, continuationOptions: TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default).Unwrap()); }
public void GetNextThrowsIfCalledBeforePreviousGetNextCompletes() { TaskCompletionSource <int>[] taskSources = Enumerable.Range(0, 2).Select(_ => new TaskCompletionSource <int>()).ToArray(); IAsyncEnumerator <int> enumerator = TaskDependentEnumerator(); AsyncItem <int> firstItemTask = enumerator.GetNextAsync(); Func <Task <Optional <int> > > despicableAct = async() => await enumerator.GetNextAsync(); despicableAct.ShouldThrow <PreviousItemNotCompletedException>(); async IAsyncEnumerator <int> TaskDependentEnumerator() { foreach (TaskCompletionSource <int> tcs in taskSources) { int item = await tcs.Task.ConfigureAwait(false); await AsyncYield.Item(item); } return(await AsyncYield.Break <int>()); } }
public static async Task ForEach <TItem, TState>(this IAsyncEnumerator <TItem> asyncEnumerator, TState state, Action <TItem, TState> action) { while (true) { Optional <TItem> item = await asyncEnumerator.GetNextAsync(); if (!item.HasValue) { break; } action(item.Value, state); } }
public async Task SynchronousExceptionIsPropagatedToGetNextCall() { const int expectedValue = 42; IAsyncEnumerator <int> enumerator = YieldItemThenThrow(); Optional <int> item = await enumerator.GetNextAsync().WithSyncContext(); item.Value.Should().Be(expectedValue); Func <Task <Optional <int> > > nextItemAct = async() => await enumerator.GetNextAsync(); nextItemAct.ShouldThrow <Exception>(); Optional <int> itemAfterException = await enumerator.GetNextAsync().WithSyncContext(); itemAfterException.HasValue.Should().BeFalse(); async IAsyncEnumerator <int> YieldItemThenThrow() { await AsyncYield.Item(expectedValue); throw new Exception("All you enumerator are belong to us"); } }
public async Task CanCallGetNextAsyncInfinitelyAfterSequenceHasEnded() { IAsyncEnumerator <int> enumerator = EmptyEnumerator(); for (int i = 0; i < 10; i++) { Optional <int> asyncItem = await enumerator.GetNextAsync().WithSyncContext(); asyncItem.HasValue.Should().BeFalse(); } async IAsyncEnumerator <int> EmptyEnumerator() { return(await AsyncYield.Break <int>()); } }
public async Task ExecutionDoesNotStartUntilNextAsyncIsCalled() { bool executionStarted = false; IAsyncEnumerator <int> enumerator = SideEffectEnumerator(); executionStarted.Should().BeFalse(); Optional <int> nextItem = await enumerator.GetNextAsync().WithSyncContext(); executionStarted.Should().BeTrue(); async IAsyncEnumerator <int> SideEffectEnumerator() { executionStarted = true; await AsyncYield.Item(42); return(await AsyncYield.Break <int>()); } }