Ejemplo n.º 1
0
        public static IQueueSource <T> Where <T>(this IQueueSource <T> queue, Func <T, Task <bool> > predicate, int?capacity = null)
        {
            AsyncQueue <T> outQueue = new AsyncQueue <T>(capacity ?? 2);

            Func <Task> worker = async delegate {
                while (true)
                {
                    Option <T> item = await queue.Dequeue(CancellationToken.None);

                    if (!item.HasValue)
                    {
                        break;
                    }
                    if (await predicate(item.Value))
                    {
                        await outQueue.Enqueue(item.Value, CancellationToken.None);
                    }
                }

                outQueue.WriteEof();
            };

            Task _dummy = Task.Run(worker);

            return(outQueue);
        }
Ejemplo n.º 2
0
        public static IQueueSource <U> Select <T, U>(this IQueueSource <T> queue, Func <T, Task <U> > func, int?capacity = null)
        {
            AsyncQueue <U> outQueue = new AsyncQueue <U>(capacity ?? 2);

            Func <Task> worker = async delegate {
                while (true)
                {
                    Option <T> item = await queue.Dequeue(CancellationToken.None);

                    if (!item.HasValue)
                    {
                        break;
                    }
                    U item2 = await func(item.Value);

                    await outQueue.Enqueue(item2, CancellationToken.None);
                }

                outQueue.WriteEof();
            };

            Task.Run(worker);

            return(outQueue);
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 4
0
        public static IQueueSource <T> ParallelWhere <T>(this IQueueSource <T> queue, ParallelWorker parallelWorker, Func <T, Task <bool> > predicate, int?capacity = null)
        {
            AsyncQueue <T> outQueue = new AsyncQueue <T>(capacity ?? 2);

            IdleDetector idleDetector = new IdleDetector();

            Func <Task> workPoster = async delegate()
            {
                while (true)
                {
                    Option <T> item = await queue.Dequeue(CancellationToken.None);

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

                    idleDetector.Enter();

                    Task doingWork = await parallelWorker.StartWorkItem
                                     (
                        async (int workerId) =>
                    {
                        try
                        {
                            if (await predicate(itemValue))
                            {
                                await outQueue.Enqueue(itemValue, CancellationToken.None);
                            }
                        }
                        finally
                        {
                            idleDetector.Leave();
                        }
                    },
                        CancellationToken.None
                                     );
                }

                await idleDetector.WaitForIdle(CancellationToken.None);

                outQueue.WriteEof();
            };

            Task.Run(workPoster);

            return(outQueue);
        }
Ejemplo n.º 5
0
        public static IEnumerable <T> AsEnumerable <T>(this IQueueSource <T> queue)
        {
            BlockingCollection <T> bc = new BlockingCollection <T>();

            Func <Task> feed = async delegate()
            {
                while (true)
                {
                    Option <T> item = await queue.Dequeue(CancellationToken.None);

                    if (item.HasValue)
                    {
                        bc.Add(item.Value);
                    }
                    else
                    {
                        break;
                    }
                }
                bc.CompleteAdding();
            };

            Task _dummy = Task.Run(feed);

            while (true)
            {
                T    item2   = default(T);
                bool success = false;
                try
                {
                    item2   = bc.Take();
                    success = true;
                }
                catch (InvalidOperationException exc)
                {
                    // BlockingCollection ran out of items
                    System.Diagnostics.Debug.WriteLine(exc);
                }

                if (!success)
                {
                    break;
                }

                yield return(item2);
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        public static IQueueSource <T> Reorder <T>(this IQueueSource <T> queue, Func <T, int> getOrder, int first, int?capacity = null)
        {
            AsyncQueue <T> outQueue = new AsyncQueue <T>(capacity ?? 2);

            Func <Task> worker = async delegate {
                int next = first;
                ImmutableDictionary <int, T> buffer = ImmutableDictionary <int, T> .Empty;
                while (true)
                {
                    Option <T> item = await queue.Dequeue(CancellationToken.None);

                    if (!item.HasValue)
                    {
                        break;
                    }
                    int order = getOrder(item.Value);
                    if (order == next)
                    {
                        await outQueue.Enqueue(item.Value, CancellationToken.None);

                        ++next;
                        while (buffer.ContainsKey(next))
                        {
                            await outQueue.Enqueue(buffer[next], CancellationToken.None);

                            buffer = buffer.Remove(next);
                            ++next;
                        }
                    }
                    else
                    {
                        buffer = buffer.Add(order, item.Value);
                    }
                }

                outQueue.WriteEof();
            };

            Task.Run(worker);

            return(outQueue);
        }