public static IEnumerableAsync <T> OnComplete <T>(this IEnumerableAsync <T> enumerableAsync, Action <T[]> onComplete, EastFive.Analytics.ILogger logger = default(ILogger)) { var enumerator = enumerableAsync.GetEnumerator(); var stack = new Stack <T>(); return(EnumerableAsync.Yield <T>( async(next, last) => { //if (!tag.IsNullOrWhiteSpace()) // Console.WriteLine($"Join[{tag}] MoveNextAsync."); if (await enumerator.MoveNextAsync()) { var current = enumerator.Current; //if (!tag.IsNullOrWhiteSpace()) // Console.WriteLine($"Join[{tag}] Passthrough on value."); stack.Push(current); return next(current); } var allValues = stack.ToArray(); if (!logger.IsDefaultOrNull()) { Console.WriteLine($"OnComplete Accumulated `{allValues.Length}` Values."); } onComplete(allValues); if (!logger.IsDefaultOrNull()) { Console.WriteLine($"OnComplete Complete."); } return last; })); }
public static IEnumerableAsync <TSelect> SelectAsyncOptional <TItem, TSelect>(this IEnumerableAsync <TItem> enumerable, Func <TItem, Func <TSelect, ISelectionResult <TSelect> >, Func <ISelectionResult <TSelect> >, Task <ISelectionResult <TSelect> > > selection) { var enumerator = enumerable.GetEnumerator(); var selections = EnumerableAsync.Yield <TSelect>( async(yieldAsync, yieldBreak) => { while (true) { if (!await enumerator.MoveNextAsync()) { return(yieldBreak); } var item = enumerator.Current; var selectionResult = await selection(item, (selected) => { return(new Selection <TSelect>(selected)); }, () => { return(new SelectionSkipped <TSelect>()); }); if (selectionResult.HasValue) { return(yieldAsync(selectionResult.Value)); } } }); return(selections); }
public static IEnumerableAsync <T> OnCompleteAsync <T>(this IEnumerableAsync <T> enumerableAsync, Func <T[], Task> onComplete, ILogger logger = default(ILogger)) { var scopedLogger = logger.CreateScope("OnCompleteAsync"); var enumerator = enumerableAsync.GetEnumerator(); var stack = new Stack <T>(); return(EnumerableAsync.Yield <T>( async(next, last) => { scopedLogger.Trace("MoveNextAsync."); if (await enumerator.MoveNextAsync()) { var current = enumerator.Current; scopedLogger.Trace("Passthrough on value."); stack.Push(current); return next(current); } var allValues = stack.ToArray(); scopedLogger.Trace($"Accumulated `{allValues.Length}` Values."); await onComplete(allValues); scopedLogger.Trace($"Complete."); return last; })); }
public static IEnumerableAsync <T> OnCompleteJoin <T>(this IEnumerableAsync <T> enumerableAsync, Func <T[], IEnumerableAsync <T> > onComplete) { var enumerator = enumerableAsync.GetEnumerator(); var stack = new Stack <T>(); var called = false; return(EnumerableAsync.Yield <T>( async(next, last) => { if (!called) { if (await enumerator.MoveNextAsync()) { var current = enumerator.Current; stack.Push(current); return next(current); } var allValues = stack.ToArray(); var completeItems = onComplete(allValues); called = true; enumerator = completeItems.GetEnumerator(); } if (await enumerator.MoveNextAsync()) { var current = enumerator.Current; return next(current); } return last; })); }
public static async Task <Accumulate <TAccumulate1, TAccumulate2> > AggregateAsync <TAccumulate1, TAccumulate2, TItem>(this IEnumerableAsync <TItem> enumerable, TAccumulate1 seed1, TAccumulate2 seed2, Func <TAccumulate1, TAccumulate2, TItem, Func <TAccumulate1, TAccumulate2, Accumulate <TAccumulate1, TAccumulate2> >, Accumulate <TAccumulate1, TAccumulate2> > funcAsync) { var accumulation = new Accumulate <TAccumulate1, TAccumulate2> { accumulation1 = seed1, accumulation2 = seed2, }; var enumeratorAsync = enumerable.GetEnumerator(); while (await enumeratorAsync.MoveNextAsync()) { var current = enumeratorAsync.Current; accumulation = funcAsync(accumulation.accumulation1, accumulation.accumulation2, current, (acc1, acc2) => new Accumulate <TAccumulate1, TAccumulate2> { accumulation1 = acc1, accumulation2 = acc2, }); } return(accumulation); }
public static IEnumerableAsync <T> JoinTask <T>(this IEnumerableAsync <T> enumerableAsync, Task task, EastFive.Analytics.ILogger logger = default(ILogger)) { var scopedLogger = logger.CreateScope($"Join[{task.Id}]"); var enumerator = enumerableAsync.GetEnumerator(); return(EnumerableAsync.Yield <T>( async(next, last) => { //if (!tag.IsNullOrWhiteSpace()) // Console.WriteLine($"Join[{tag}] MoveNextAsync."); if (await enumerator.MoveNextAsync()) { //if (!tag.IsNullOrWhiteSpace()) // Console.WriteLine($"Join[{tag}] Passthrough on value."); return next(enumerator.Current); } scopedLogger.Trace($"Joining Task."); await task; scopedLogger.Trace($"Complete."); return last; })); }
public static async Task ForEachAsync <TSource>(this IEnumerableAsync <TSource> source, Func <TSource, Task> iterationAction, CancellationToken cancellationToken) { using (IEnumeratorAsync <TSource> en = source.GetEnumerator()) while (await en.MoveNextAsync(cancellationToken)) { await iterationAction(en.Current); } }
public static IEnumerableAsync <TItem> Throttle <TItem>(this IEnumerableAsync <Task <TItem> > enumerable, int desiredRunCount = 1, ILogger log = default(ILogger)) { var logScope = log.CreateScope($"Throttle"); var taskList = new List <Task <TItem> >(); var locker = new AutoResetEvent(true); var enumerator = enumerable.GetEnumerator(); var moving = true; return(Yield <TItem>( async(yieldReturn, yieldBreak) => { while (true) { locker.WaitOne(); if (taskList.Count >= desiredRunCount) { Task <TItem>[] tasks = taskList.ToArray(); var finishedTask = await Task.WhenAny(tasks); taskList.Remove(finishedTask); locker.Set(); var item = await finishedTask; return yieldReturn(item); } if (!moving) { if (!taskList.Any()) { locker.Set(); return yieldBreak; } Task <TItem>[] tasks = taskList.ToArray(); var finishedTask = await Task.WhenAny(tasks); taskList.Remove(finishedTask); locker.Set(); var item = await finishedTask; return yieldReturn(item); } locker.Set(); if (!await enumerator.MoveNextAsync()) { moving = false; continue; } var nextTask = enumerator.Current; locker.WaitOne(); taskList.Add(nextTask); locker.Set(); } })); }
async Task IMultiplexingEnumerableOpen.Open() { if (Interlocked.CompareExchange(ref isOpen, 1, 0) != 0) { throw new InvalidOperationException("Can not open twice"); } enumerator = await inner.GetEnumerator(); awaitedEnumerators = totalEnumerators; open.SetResult(1); }
public static async Task <TAccumulate> AggregateAsync <TAccumulate, TItem>(this IEnumerableAsync <TItem> enumerable, TAccumulate seed, Func <TAccumulate, TItem, TAccumulate> funcAsync) { var accumulation = seed; var enumeratorAsync = enumerable.GetEnumerator(); while (await enumeratorAsync.MoveNextAsync()) { var current = enumeratorAsync.Current; accumulation = funcAsync(accumulation, current); } return(accumulation); }
public static IEnumerableAsync <T> TakeAsync <T>(this IEnumerableAsync <T> items, int limit) { YieldCallbackAsync <T> yieldAsync = async yield => { using (var enumerator = items.GetEnumerator()) { while (limit > 0 && await enumerator.MoveNextAsync(yield)) { limit--; } } }; return(new EnumerableAsync <T>(yieldAsync)); }
public async static Task <bool> ForEach <T>(this IEnumerableAsync <T> input, Func <T, Task <bool> > action) { var it = await input.GetEnumerator(); return(await TryFinallyAsync( async() => { bool lastActionResult = true; for (; await it.MoveNext() && (lastActionResult = await action(it.Current));) { } ; return lastActionResult; }, it.Dispose )); }
public DictionaryAsync(IEnumerableAsync <TElement> enumerable, Func <TElement, TKey> keySelector, Func <TElement, TValue> valueSelector, Func <TKey, TKey, bool> comparison = default(Func <TKey, TKey, bool>)) { this.enumerable = enumerable; this.dictionary = new Dictionary <TKey, TValue>(); this.keySelector = keySelector; this.valueSelector = valueSelector; this.tryNextEnumerator = enumerable.GetEnumerator(); this.dictionaryLock = new AutoResetEvent(true); if (comparison.IsDefaultOrNull()) { comparison = (key1, key2) => key1.Equals(key2); } this.comparison = comparison; }
public static async Task <IEnumerable <T> > Async <T>(this IEnumerableAsync <T> enumerable, Analytics.ILogger logger = default(Analytics.ILogger)) { var scopedLogger = logger.CreateScope("Async"); var enumerator = enumerable.GetEnumerator(); var firstStep = new Step <T>(default(T)); var step = firstStep; scopedLogger.Trace("Moving to next step"); while (await enumerator.MoveNextAsync()) { scopedLogger.Trace("Moved to next step"); var nextStep = new Step <T>(enumerator.Current); step.next = nextStep; step = nextStep; } scopedLogger.Trace("Last step"); return(new StepEnumerable <T>(firstStep)); }
public static async Task <TResult> SelectOptionalAsync <TItem, TSelect, TCarry, TResult>(this IEnumerableAsync <TItem> enumerable, TCarry carry, Func <TItem, TCarry, Func <TSelect, TCarry, ISelectionResult <TSelect> >, Func <TCarry, ISelectionResult <TSelect> >, Task <ISelectionResult <TSelect> > > selectionAsync, Func <TSelect[], TCarry, TResult> aggregation) { var enumerator = enumerable.GetEnumerator(); var selecteds = default(IEnumerableAsync <TSelect>); // var completedEvent = new System.Threading.ManualResetEvent(false); selecteds = EnumerableAsync.Yield <TSelect>( async(yieldReturn, yieldBreak) => { while (true) { if (!await enumerator.MoveNextAsync()) { return(yieldBreak); } var yieldResult = await selectionAsync(enumerator.Current, carry, (selected, carryUpdated) => { carry = carryUpdated; return(new Selection <TSelect>(selected)); }, (carryUpdated) => { carry = carryUpdated; return(new SelectionSkipped <TSelect>()); }); if (yieldResult.HasValue) { return(yieldReturn(yieldResult.Value)); } } }); var selectedResults = (await selecteds.Async()).ToArray(); var aggregated = aggregation(selectedResults, carry); return(aggregated); }
public static IEnumerableAsync <Tuple <T1, T2> > Zip <T1, T2>(this IEnumerableAsync <T1> input1, IEnumerableAsync <T2> input2) { return(Produce <Tuple <T1, T2> >(async yieldAsync => { IEnumeratorAsync <T1> enum1 = NullEnumerator <T1> .Instance; IEnumeratorAsync <T2> enum2 = NullEnumerator <T2> .Instance; await TryFinallyAsync( async() => { enum1 = await input1.GetEnumerator(); enum2 = await input2.GetEnumerator(); while (AllTrue(await Task.WhenAll(enum1.MoveNext(), enum2.MoveNext()))) { await yieldAsync.YieldAsync(Tuple.Create(enum1.Current, enum2.Current)); } return 0; }, () => Task.WhenAll(enum1.Dispose(), enum2.Dispose()) ); })); }
public static TResult SelectOptional <TItem, TSelect, TCarry, TResult>(this IEnumerableAsync <TItem> enumerable, TCarry carry, Func <TItem, TCarry, Func <TSelect, TCarry, TResult>, Func <TCarry, TResult>, TResult> selection, Func <IEnumerableAsync <TSelect>, TCarry, TResult> aggregation) { var enumerator = enumerable.GetEnumerator(); var selecteds = default(IEnumerableAsync <TSelect>); TResult aggregated = default(TResult); var completedEvent = new System.Threading.AutoResetEvent(false); selecteds = EnumerableAsync.Yield <TSelect>( async(yieldReturn, yieldBreak) => { if (!await enumerator.MoveNextAsync()) { return(yieldBreak); } var yieldResult = default(IYieldResult <TSelect>); var discard = selection(enumerator.Current, carry, (selected, carryUpdated) => { yieldResult = yieldReturn(selected); completedEvent.WaitOne(); return(aggregated); }, (carryUpdated) => { completedEvent.WaitOne(); return(aggregated); }); return(yieldResult); }); aggregated = aggregation(selecteds, carry); completedEvent.Set(); return(aggregated); }
public static IEnumerableAsync <T> OnCompleteAsyncAppend <T>(this IEnumerableAsync <T> enumerableAsync, Func <T[], Task <T[]> > onComplete) { var enumerator = enumerableAsync.GetEnumerator(); var stack = new Stack <T>(); var called = false; var completeItemsIndex = 0; var completeItems = default(T[]); return(EnumerableAsync.Yield <T>( async(next, last) => { if (!called) { if (await enumerator.MoveNextAsync()) { var current = enumerator.Current; stack.Push(current); return next(current); } var allValues = stack.ToArray(); completeItems = await onComplete(allValues); called = true; } if (completeItemsIndex < completeItems.Length) { var current = completeItems[completeItemsIndex]; completeItemsIndex++; return next(current); } return last; })); }
public IEnumeratorAsync <TResult> GetEnumerator() => new FuncEnumerator <TSource, TResult>(_source.GetEnumerator(), _func);
public static async Task <bool> FirstAsync <T>(this IEnumerableAsync <T> items, T action) { var enumerator = items.GetEnumerator(); return(await enumerator.MoveNextAsync(action)); }
public IEnumeratorAsync <TSource> GetEnumerator() => new WhereEnumerator <TSource>(_source.GetEnumerator(), _predicate);
public override async Task WriteResponseAsync(Stream responseStream) { using (var streamWriter = this.Request.TryGetAcceptCharset(out Encoding writerEncoding) ? new StreamWriter(responseStream, writerEncoding) : new StreamWriter(responseStream, new UTF8Encoding(false))) { var enumerator = objectsAsync.GetEnumerator(); try { var castings = typeof(T) .GetPropertyAndFieldsWithAttributesInterface <ICast <string> >() .ToArray(); bool first = true; if (includeHeaders) { var headerCsvStrings = castings .Select( tpl => tpl.Item1.TryGetAttributeInterface(out IProvideApiValue apiValueProvider) ? apiValueProvider.PropertyName.Replace('_', ' ') : " ") .Join(","); await streamWriter.WriteAsync(headerCsvStrings); await streamWriter.FlushAsync(); first = false; } while (await enumerator.MoveNextAsync()) { if (!first) { await streamWriter.WriteAsync('\r'); await streamWriter.FlushAsync(); } first = false; var obj = enumerator.Current; var contentCsvStrings = castings .Select( tpl => tpl.Item2.Cast( tpl.Item1.GetPropertyOrFieldValue(obj), tpl.Item1.GetPropertyOrFieldType(), String.Empty, tpl.Item1, value => value, () => string.Empty)) .Join(","); await streamWriter.WriteAsync(contentCsvStrings); await streamWriter.FlushAsync(); } } catch (Exception ex) { await streamWriter.WriteAsync(ex.Message); } finally { await streamWriter.FlushAsync(); } } }
public static IEnumerableAsync <IGroupingAsync <TKey, TSource> > GroupBy <TSource, TKey>(this IEnumerableAsync <TSource> enumerable, Func <TSource, TKey> keySelector) { var accumulation = new Dictionary <TKey, GroupingAsync <TKey, TSource> >(); var enumeratorAsync = enumerable.GetEnumerator(); var keyQueue = new Queue <TKey>(); var mutex = new AutoResetEvent(true); return(Yield <IGroupingAsync <TKey, TSource> >( async(yieldReturn, yieldBreak) => { async Task <bool> MoveNextAsync() { mutex.WaitOne(); var current = default(TSource); try { if (!await enumeratorAsync.MoveNextAsync()) { return false; } current = enumeratorAsync.Current; } finally { mutex.Set(); } var key = keySelector(current); lock (accumulation) { if (!accumulation.ContainsKey(key)) { lock (keyQueue) { keyQueue.Enqueue(key); } var grouping = new GroupingAsync <TKey, TSource>( key, async() => { var didMove = await MoveNextAsync(); return didMove; }); accumulation.Add(key, grouping); } accumulation[key].AddItem(current); } return true; } while (true) { var key = default(TKey); bool any = false; lock (keyQueue) { any = keyQueue.Any(); if (any) { key = keyQueue.Dequeue(); } } if (any) { lock (accumulation) { return yieldReturn(accumulation[key]); } } var moved = await MoveNextAsync(); if (moved) { continue; } return yieldBreak; } })); }
public static Task <bool> AnyAsync <T>(this IEnumerableAsync <T> enumerable) { var enumerator = enumerable.GetEnumerator(); return(enumerator.MoveNextAsync()); }
public static async Task <T> FirstOrDefaultAsync <T>(this IEnumerableAsync <T> source, CancellationToken cancellationToken) { using (IEnumeratorAsync <T> en = source.GetEnumerator()) return(await en.MoveNextAsync(cancellationToken) ? en.Current : default(T)); }
public override async Task WriteResponseAsync(Stream responseStream) { using (var streamWriter = this.Request.TryGetAcceptCharset(out Encoding writerEncoding) ? new StreamWriter(responseStream, writerEncoding) : new StreamWriter(responseStream, new UTF8Encoding(false))) { var settings = new JsonSerializerSettings(); settings.Converters.Add(new Serialization.Converter(this.Request)); settings.DefaultValueHandling = DefaultValueHandling.Include; var enumerator = objectsAsync.GetEnumerator(); await streamWriter.WriteAsync('['); await streamWriter.FlushAsync(); bool first = true; try { while (await enumerator.MoveNextAsync()) { if (!first) { await streamWriter.WriteAsync(','); await streamWriter.FlushAsync(); } first = false; var obj = enumerator.Current; var objType = (obj == null)? typeof(T) : obj.GetType(); if (!objType.ContainsAttributeInterface <IProvideSerialization>()) { var contentJsonString = JsonConvert.SerializeObject(obj, settings); await streamWriter.WriteAsync(contentJsonString); await streamWriter.FlushAsync(); continue; } var serializationProvider = objType .GetAttributesInterface <IProvideSerialization>() .OrderByDescending(x => x.GetPreference(this.Request)) .First(); await serializationProvider.SerializeAsync(responseStream, application, this.Request, this.parameterInfo, obj); await streamWriter.FlushAsync(); } } catch (Exception ex) { await streamWriter.WriteAsync(ex.Message); } finally { await streamWriter.WriteAsync(']'); await streamWriter.FlushAsync(); } } }