예제 #1
0
        public async Task TestSequentialEnumeratorAsync()
        {
            var start           = MAX_ITEMS;
            var completionState = new Int32[start];
            var r = new Random();
            MoveNextAsyncDelegate <Int32> moveNext = async() =>
            {
                var decremented = Interlocked.Decrement(ref start);
                await Task.Delay(r.Next(100, 500));

                return(decremented >= 0, MAX_ITEMS - decremented - 1);
            };

            var enumerable = AsyncEnumerationFactory.CreateSequentialEnumerable(() => AsyncEnumerationFactory.CreateSequentialStartInfo(
                                                                                    moveNext,
                                                                                    null
                                                                                    ),
                                                                                DefaultAsyncProvider.Instance);
            Func <Int32, Task> callback = async idx =>
            {
                await Task.Delay(r.Next(100, 900));

                Assert.IsTrue(completionState.Take(idx).All(s => s == 1));
                Interlocked.Increment(ref completionState[idx]);
            };
            var itemsEncountered = await enumerable.EnumerateAsync(callback);

            Assert.AreEqual(itemsEncountered, completionState.Length);
            Assert.IsTrue(completionState.All(s => s == 1));
        }
예제 #2
0
 internal static SequentialEnumeratorCurrentInfo <T> GetInstance <T>(
     MoveNextAsyncDelegate <T> moveNext,
     EnumerationEndedDelegate dispose
     )
 {
     return((SequentialEnumeratorCurrentInfo <T>)GetFactory(typeof(T))?.Invoke(moveNext, dispose) ?? new SequentialEnumeratorCurrentInfoWithObject <T>(moveNext, dispose));
 }
예제 #3
0
 /// <summary>
 /// Initializes a new <see cref="SequentialEnumerationStartInfo{T}"/> with given callbacks.
 /// </summary>
 /// <param name="moveNext">The callback to fetch next item.</param>
 /// <param name="dispose">The optional callback to dispose enumerator. May be <c>null</c>.</param>
 /// <remarks>
 /// If <paramref name="moveNext"/> is <c>null</c>, then enumeration ends immediately.
 /// </remarks>
 /// <seealso cref="AsyncEnumerationFactory.CreateSequentialStartInfo"/>
 public SequentialEnumerationStartInfo(
     MoveNextAsyncDelegate <T> moveNext,
     EnumerationEndedDelegate dispose
     )
 {
     this.MoveNext = moveNext;
     this.Dispose  = dispose;
 }
예제 #4
0
 public Task TestSequentialEnumeratorCompletelySync()
 {
     var start           = MAX_ITEMS;
     var completionState = new Int32[start];
     var r = new Random();
     MoveNextAsyncDelegate <Int32> moveNext = () =>
     {
         var decremented = Interlocked.Decrement(ref start);
         return(new ValueTask <(Boolean, Int32)>((decremented >= 0, MAX_ITEMS - decremented - 1)));
     };
예제 #5
0
 public CurrentInfo(
     T current,
     MoveNextAsyncDelegate <T> moveNext,
     DisposeAsyncDelegate disposeDelegate
     )
 {
     this.MoveNext = moveNext;
     this.Current  = current ?? throw new ArgumentNullException(nameof(current));
     this.Dispose  = disposeDelegate;
 }
예제 #6
0
 /// <summary>
 /// Creates a new instance of <see cref="IAsyncEnumerator{T}"/> which fetches one item at a time using given callback.
 /// </summary>
 /// <typeparam name="T">The type of items being enumerated.</typeparam>
 /// <param name="moveNext">The callback for potentially asynchronously fetching next item.</param>
 /// <param name="dispose">The callback to dispose enumerator.</param>
 /// <returns>A new instance of <see cref="IAsyncEnumerator{T}"/> which behaves like <paramref name="moveNext"/> and <paramref name="dispose"/> specify.</returns>
 /// <remarks>
 /// The returned <see cref="IAsyncEnumerator{T}"/> will have guard code to prevent concurrent invocation.
 /// </remarks>
 public static IAsyncEnumerator <T> CreateSequentialEnumerator <T>(
     MoveNextAsyncDelegate <T> moveNext,
     EnumerationEndedDelegate dispose
     ) => new AsyncEnumerator <T>(SequentialCurrentInfoFactory.GetInstance(moveNext, dispose));
예제 #7
0
 /// <summary>
 /// Helper method to invoke constructor of <see cref="SequentialEnumerationStartInfo{T}"/> without explicitly specifying generic type arguments.
 /// </summary>
 /// <typeparam name="T">The type of items being enumerated.</typeparam>
 /// <param name="moveNext">The callback for potentially asynchronously fetching next item.</param>
 /// <param name="dispose">The callback to dispose enumerator.</param>
 /// <returns>A new <see cref="SequentialEnumerationStartInfo{T}"/>.</returns>
 /// <seealso cref="SequentialEnumerationStartInfo{T}.SequentialEnumerationStartInfo(MoveNextAsyncDelegate{T}, EnumerationEndedDelegate)"/>
 public static SequentialEnumerationStartInfo <T> CreateSequentialStartInfo <T>(
     MoveNextAsyncDelegate <T> moveNext,
     EnumerationEndedDelegate dispose
     ) => new SequentialEnumerationStartInfo <T>(moveNext, dispose);