Esempio n. 1
0
        /// <summary>
        ///     ContinueWith specified <see cref="Action{T}" /> on each <see cref="Task" /> on the GraphSet
        /// </summary>
        /// <typeparam name="T">Type of the elements</typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns><see cref="GraphSet{TaskPair}" /> with continuation tasks.</returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ContinueWith <T>(this GraphSet <TaskPair <T> > set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var tasks   = new Dictionary <GraphNode <TaskPair <T> >, Task>();
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x.Value)
            {
                Task = x.Task
            });

            foreach (var node in taskSet.GetNodes())
            {
                tasks[node]     = node.Value.Task;
                node.Value.Task = null;
            }
            var nodes = taskSet.GetNodes().Where(n => n.Parents.Count == 0).ToArray();

            foreach (var node in nodes)
            {
                node.Value.Task = tasks[node].ContinueWith(t => action(node.Value.Value));
            }
            var queue = new Queue <GraphNode <TaskPair <T> > >(nodes);

            while (queue.Any())
            {
                var node = queue.Dequeue();
                if (node.Value.Task == null)
                {
                    var allParentsHaveTask = node.Parents.All(x => x.Value.Task != null);
                    if (allParentsHaveTask)
                    {
                        var list = node.Parents.Select(x => x.Value.Task).ToList();
                        list.Add(tasks[node]);
                        node.Value.Task = Task.Factory.ContinueWhenAll(
                            list.ToArray(),
                            x => action(node.Value.Value));
                    }
                    queue.Enqueue(node);
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        if (child.Value.Task == null)
                        {
                            queue.Enqueue(child);
                        }
                    }
                }
            }
            return(taskSet);
        }
Esempio n. 2
0
        /// <summary>
        ///     ContinueWith specified <see cref="Action{T}" /> on the leaves of the GraphSet.
        /// </summary>
        /// <typeparam name="T">Type of the elements</typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns><see cref="GraphSet{TaskPair}" /> with continuation tasks.</returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ContinueOnLeavesWith <T>(this GraphSet <TaskPair <T> > set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x.Value)
            {
                Task = x.Task
            });
            var graphNodes = taskSet.GetNodes().Where(x => x.Children.Count == 0);

            foreach (var node in graphNodes)
            {
                node.Value.Task = node.Value.Task.ContinueWith(x => action(node.Value.Value));
            }
            return(taskSet);
        }
Esempio n. 3
0
        /// <summary>
        ///     Transforms a <see cref="GraphSet{T}" /> to a GraphSet of Task executing the <see cref="Action{T}" /> on
        ///     each of the nodes while respecting the graph order.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns>
        ///     <see cref="GraphSet{TaskPair}" />
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ToTaskGraph <T>(this GraphSet <T> set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x));
            var nodes   = taskSet.GetNodes().Where(n => n.Parents.Count == 0).ToArray();

            foreach (var node in nodes)
            {
                node.Value.Task = Task.Factory.StartNew(() => { action(node.Value.Value); });
            }
            var queue = new Queue <GraphNode <TaskPair <T> > >(nodes);

            while (queue.Any())
            {
                var node = queue.Dequeue();
                if (node.Value.Task == null)
                {
                    var allParentsHaveTask = node.Parents.All(x => x.Value.Task != null);
                    if (allParentsHaveTask)
                    {
                        node.Value.Task = Task.Factory.ContinueWhenAll(
                            node.Parents.Select(x => x.Value.Task).ToArray(),
                            x => { action(node.Value.Value); });
                    }
                    queue.Enqueue(node);
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        if (child.Value.Task == null)
                        {
                            queue.Enqueue(child);
                        }
                    }
                }
            }
            return(taskSet);
        }