コード例 #1
0
        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;
            }));
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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;
            }));
        }
コード例 #4
0
        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;
            }));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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;
            }));
        }
コード例 #7
0
 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);
         }
 }
コード例 #8
0
        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();
                }
            }));
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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));
        }
コード例 #12
0
        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
                       ));
        }
コード例 #13
0
            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;
            }
コード例 #14
0
        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));
        }
コード例 #15
0
        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);
        }
コード例 #16
0
 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())
             );
     }));
 }
コード例 #17
0
        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);
        }
コード例 #18
0
        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;
            }));
        }
コード例 #19
0
 public IEnumeratorAsync <TResult> GetEnumerator()
 => new FuncEnumerator <TSource, TResult>(_source.GetEnumerator(), _func);
コード例 #20
0
        public static async Task <bool> FirstAsync <T>(this IEnumerableAsync <T> items, T action)
        {
            var enumerator = items.GetEnumerator();

            return(await enumerator.MoveNextAsync(action));
        }
コード例 #21
0
 public IEnumeratorAsync <TSource> GetEnumerator()
 => new WhereEnumerator <TSource>(_source.GetEnumerator(), _predicate);
コード例 #22
0
        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();
                }
            }
        }
コード例 #23
0
        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;
                }
            }));
        }
コード例 #24
0
        public static Task <bool> AnyAsync <T>(this IEnumerableAsync <T> enumerable)
        {
            var enumerator = enumerable.GetEnumerator();

            return(enumerator.MoveNextAsync());
        }
コード例 #25
0
 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));
 }
コード例 #26
0
        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();
                }
            }
        }