public static IEnumerable <int> Range(int start, int count) { long max = ((long)start) + count - 1; if (count < 0 || max > Int32.MaxValue) { throw Error.ArgumentOutOfRange("count"); } if (count == 0) { return(new EmptyPartition <int>()); } return(new RangeIterator(start, count)); }
public static IEnumerable <TResult> Repeat <TResult>(TResult element, int count) { if (count < 0) { throw Error.ArgumentOutOfRange(nameof(count)); } if (count == 0) { return(EmptyPartition <TResult> .Instance); } return(new RepeatIterator <TResult>(element, count)); }
TElement IList <TElement> .this[int index] { get { if (index < 0 || index >= count) { throw Error.ArgumentOutOfRange("index"); } return(elements[index]); } set { throw Error.NotSupported(); } }
/// <summary> /// Applies a timeout policy for each element in the async-enumerable sequence. /// If the next element isn't received within the specified timeout duration starting from its predecessor, a TimeoutException is propagated to the observer. /// </summary> /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam> /// <param name="source">Source sequence to perform a timeout for.</param> /// <param name="timeout">Maximum duration between values before a timeout occurs.</param> /// <returns>The source sequence with a TimeoutException in case of a timeout.</returns> /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="timeout"/> is less than TimeSpan.Zero.</exception> /// <exception cref="TimeoutException">(Asynchronous) If no element is produced within <paramref name="timeout"/> from the previous element.</exception> /// <remarks> /// <para> /// In case you only want to timeout on the first element, consider using the <see cref="Amb{TSource}(IAsyncEnumerable{TSource}, IAsyncEnumerable{TSource})"/> /// operator applied to the source sequence and a delayed <see cref="Throw{TResult}(Exception)"/> sequence. /// <!-- FIXME: Timeout with initial and per item timeout option not implemented yet. /// Alternatively, the general-purpose overload /// of Timeout, <see cref="Timeout{TSource, TTimeout}(IObservable{TSource}, IObservable{TTimeout}, Func{TSource, IObservable{TTimeout}})"/> can be used. /// --> /// </para> /// <para> /// Specifying a TimeSpan.Zero value for <paramref name="timeout"/> is not recommended but supported, causing timeout timers to be scheduled that are due /// immediately. However, this doesn't guarantee a timeout will occur, even for the first element. This is a side-effect of the asynchrony introduced by the /// scheduler, where the action to propagate a timeout may not execute immediately, despite the TimeSpan.Zero due time. In such cases, the next element may /// arrive before the scheduler gets a chance to run the timeout action. /// </para> /// </remarks> public static IAsyncEnumerable <TSource> Timeout <TSource>(this IAsyncEnumerable <TSource> source, TimeSpan timeout) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } var num = (long)timeout.TotalMilliseconds; if (num < -1L || num > int.MaxValue) { throw Error.ArgumentOutOfRange(nameof(timeout)); } return(new TimeoutAsyncIterator <TSource>(source, timeout)); }
public static IEnumerable <int> Range(int start, int count) { long max = ((long)start) + count - 1; if (count < 0 || max > int.MaxValue) { throw Error.ArgumentOutOfRange(nameof(count)); } if (count == 0) { return(Empty <int>()); } return(new RangeIterator(start, count)); }
public static IAsyncEnumerable <IList <TSource> > Buffer <TSource>(this IAsyncEnumerable <TSource> source, int count, int skip) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count <= 0) { throw Error.ArgumentOutOfRange(nameof(count)); } if (skip <= 0) { throw Error.ArgumentOutOfRange(nameof(skip)); } return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <IList <TSource> > Core(CancellationToken cancellationToken) { var buffers = new Queue <IList <TSource> >(); var index = 0; await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false)) { if (index++ % skip == 0) { buffers.Enqueue(new List <TSource>(count)); } foreach (var buffer in buffers) { buffer.Add(item); } if (buffers.Count > 0 && buffers.Peek().Count == count) { yield return(buffers.Dequeue()); } } while (buffers.Count > 0) { yield return(buffers.Dequeue()); } } }
public static TSource ElementAt <TSource>(this IEnumerable <TSource> source, int index) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } IPartition <TSource> partition = source as IPartition <TSource>; if (partition != null) { bool found; TSource element = partition.TryGetElementAt(index, out found); if (found) { return(element); } } else { IList <TSource> list = source as IList <TSource>; if (list != null) { return(list[index]); } if (index >= 0) { using (IEnumerator <TSource> e = source.GetEnumerator()) { while (e.MoveNext()) { if (index == 0) { return(e.Current); } index--; } } } } throw Error.ArgumentOutOfRange(nameof(index)); }
public static IAsyncEnumerable <int> Range(int start, int count) { if (count < 0) { throw Error.ArgumentOutOfRange(nameof(count)); } var end = (long)start + count - 1L; if (end > int.MaxValue) { throw Error.ArgumentOutOfRange(nameof(count)); } if (count == 0) { return(Empty <int>()); } return(new RangeAsyncIterator(start, count)); }
public static IAsyncEnumerable <IList <TSource> > Buffer <TSource>(this IAsyncEnumerable <TSource> source, int count) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count <= 0) { throw Error.ArgumentOutOfRange(nameof(count)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <IList <TSource> > Core(CancellationToken cancellationToken) { var buffer = new List <TSource>(count); await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { buffer.Add(item); if (buffer.Count == count) { yield return(buffer); buffer = new List <TSource>(count); } } if (buffer.Count > 0) { yield return(buffer); } } #else return(new BufferAsyncIterator <TSource>(source, count, count)); #endif }
static async ValueTask <TSource> Core(IAsyncEnumerable <TSource> _source, int _index, CancellationToken _cancellationToken) { if (_source is IAsyncPartition <TSource> p) { var first = await p.TryGetElementAtAsync(_index, _cancellationToken).ConfigureAwait(false); if (first.HasValue) { return(first.Value); } } else { if (_source is IList <TSource> list) { return(list[_index]); } if (_index >= 0) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { if (_index == 0) { return(item); } _index--; } } } // NB: Even though index is captured, no closure is created. // The nameof expression is lowered to a literal prior to creating closures. throw Error.ArgumentOutOfRange(nameof(index)); }
/// <summary> /// Repeats the async-enumerable sequence a specified number of times. /// </summary> /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam> /// <param name="source">Observable sequence to repeat.</param> /// <param name="count">Number of times to repeat the sequence.</param> /// <returns>The async-enumerable sequence producing the elements of the given sequence repeatedly.</returns> /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="count"/> is less than zero.</exception> public static IAsyncEnumerable <TSource> Repeat <TSource>(this IAsyncEnumerable <TSource> source, int count) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count < 0) { throw Error.ArgumentOutOfRange(nameof(count)); } return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { for (var i = 0; i < count; i++) { await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false)) { yield return(item); } } } }
public TElement ElementAt(int index) { throw Error.ArgumentOutOfRange("index"); }