Пример #1
0
        public static Func <Task> ForEach <T>(IQueueSource <T> source, Func <ForEachInfo <T>, Task> processAsync, Func <Task> onCloseAsync, ExceptionCollector ec)
        {
            Func <Task> t = async delegate()
            {
                try
                {
                    while (true)
                    {
                        var item = await source.Dequeue(ec.CancellationToken);

                        if (!item.HasValue)
                        {
                            break;
                        }
                        try
                        {
                            await processAsync(new ForEachInfo <T>(item.Value, 0, 0, ec.CancellationToken));
                        }
                        catch (Exception exc)
                        {
                            ec.Add(exc);
                            break;
                        }
                    }
                }
                finally
                {
                    if (onCloseAsync != null)
                    {
                        try
                        {
                            await onCloseAsync();
                        }
                        catch (Exception exc)
                        {
                            ec.Add(exc);
                        }
                    }
                }
            };

            return(t);
        }
Пример #2
0
        public static Func <Task> ForEach <T>(IQueueSource <T>[] sources, InputPriorities inputPriorities, Func <ForEachInfo <T>, Task> processAsync, Func <Task> onCloseAsync, ExceptionCollector ec)
        {
            Func <Task> t = async delegate()
            {
                try
                {
                    int    sourceCount           = sources.Length;
                    bool[] atEof                 = new bool[sourceCount];
                    RoundRobinLoopGenerator loop = new RoundRobinLoopGenerator(sourceCount, inputPriorities);
                    while (!(atEof.All(e => e)))
                    {
                        var ops = Utils.OperationStarters <int, Option <T> >();

                        loop.ForEach
                        (
                            j => { ops = ops.AddIf(!atEof[j], j, Utils.StartableGet <T, Option <T> >(sources[j], a => new Some <T>(a), new None <T>())); }
                        );

                        Tuple <int, Option <T> > result = await ops.CompleteAny(ec.CancellationToken);

                        if (result.Item2.HasValue)
                        {
                            try
                            {
                                await processAsync(new ForEachInfo <T>(result.Item2.Value, result.Item1, 0, ec.CancellationToken));
                            }
                            catch (Exception exc)
                            {
                                ec.Add(exc);
                            }
                        }
                        else
                        {
                            atEof[result.Item1] = true;
                        }
                    }
                }
                finally
                {
                    if (onCloseAsync != null)
                    {
                        try
                        {
                            await onCloseAsync();
                        }
                        catch (Exception exc)
                        {
                            ec.Add(exc);
                        }
                    }
                }
            };

            return(t);
        }
Пример #3
0
        public static Func <Task> ParallelForEach <T>(IQueueSource <T> source, ParallelWorker parallelWorker, Func <ForEachInfo <T>, Task> processAsync, Func <Task> onCloseAsync, ExceptionCollector ec)
        {
            Func <Task> t = async delegate()
            {
                IdleDetector idleDetector = new IdleDetector();
                try
                {
                    while (true)
                    {
                        var item = await source.Dequeue(ec.CancellationToken);

                        if (!item.HasValue)
                        {
                            break;
                        }
                        T itemValue = item.Value;

                        idleDetector.Enter();

                        await parallelWorker.StartWorkItem
                        (
                            async workerId =>
                        {
                            try
                            {
                                await processAsync(new ForEachInfo <T>(itemValue, 0, workerId, ec.CancellationToken));
                            }
                            catch (Exception exc)
                            {
                                ec.Add(exc);
                            }
                            finally
                            {
                                idleDetector.Leave();
                            }
                        },
                            ec.CancellationToken
                        );
                    }
                }
                finally
                {
                    await idleDetector.WaitForIdle(CancellationToken.None);

                    if (onCloseAsync != null)
                    {
                        try
                        {
                            await onCloseAsync();
                        }
                        catch (Exception exc)
                        {
                            ec.Add(exc);
                        }
                    }
                }
            };

            return(t);
        }