Пример #1
0
        public async Task TestDataBroadcaster1()
        {
            var random     = new Random();
            var dataCopier = new DataBroadcaster <int>();

            int sum1 = 0;
            int sum2 = 0;

            var action1 = new ActionBlock <int>(i => sum1 = sum1 + i);
            var action2 = new ActionBlock <int>(i => sum2 = sum2 + i);

            dataCopier.LinkTo(DataflowUtils.FromBlock(action1));
            dataCopier.LinkTo(DataflowUtils.FromBlock(action2));

            for (int j = 0; j < 1000; j++)
            {
                dataCopier.InputBlock.Post((int)(random.NextDouble() * 10000));
            }

            dataCopier.InputBlock.Complete();

            await TaskEx.AwaitableWhenAll(action1.Completion, action2.Completion);

            Console.WriteLine("sum1 = {0} , sum2 = {1}", sum1, sum2);
            Assert.AreEqual(sum1, sum2);
        }
Пример #2
0
        public async Task TestDataBroadcaster2()
        {
            var random = new Random();
            var buffer = new BufferBlock <int>();

            int sum1 = 0;
            int sum2 = 0;
            int sum3 = 0;

            var action1 = new ActionBlock <int>(i => sum1 = sum1 + i);
            var action2 = new ActionBlock <int>(i => sum2 = sum2 + i);
            var action3 = new ActionBlock <int>(i => sum3 = sum3 + i);

            buffer.ToDataflow().LinkToMultiple(new [] { action1, action2, action3 }.Select(a => a.ToDataflow()).ToArray());

            for (int j = 0; j < 1000; j++)
            {
                buffer.Post((int)(random.NextDouble() * 10000));
            }

            buffer.Complete();

            await TaskEx.AwaitableWhenAll(action1.Completion, action2.Completion, action3.Completion);

            Console.WriteLine("sum1 = {0} , sum2 = {1}", sum1, sum2);
            Assert.AreEqual(sum1, sum2);
            Assert.AreEqual(sum1, sum3);
        }
Пример #3
0
        public async Task TestDataBrancher1()
        {
            var random     = new Random();
            var dataCopier = new DataBrancher <int>();

            int sum1 = 0;
            int sum2 = 0;

            var action1 = new ActionBlock <int>(i => sum1 = sum1 + i);
            var action2 = new ActionBlock <int>(i => sum2 = sum2 + i);

            dataCopier.OutputBlock.LinkTo(action1, new DataflowLinkOptions()
            {
                PropagateCompletion = true
            });
            dataCopier.CopiedOutputBlock.LinkTo(action2, new DataflowLinkOptions()
            {
                PropagateCompletion = true
            });

            for (int j = 0; j < 1000; j++)
            {
                dataCopier.InputBlock.Post((int)(random.NextDouble() * 10000));
            }

            dataCopier.InputBlock.Complete();

            await TaskEx.AwaitableWhenAll(action1.Completion, action2.Completion);

            Console.WriteLine("sum1 = {0} , sum2 = {1}", sum1, sum2);
            Assert.AreEqual(sum1, sum2);
        }
Пример #4
0
        protected virtual async Task GetCompletionTask()
        {
            if (m_children.Count == 0)
            {
                throw new NoChildRegisteredException(this);
            }

            ImmutableList <IChildMeta> childrenSnapShot;

            do
            {
                childrenSnapShot = m_children;
                await TaskEx.AwaitableWhenAll(childrenSnapShot.Select(b => b.ChildCompletion).ToArray());
            } while (!object.ReferenceEquals(m_children, childrenSnapShot));

            this.CleanUp();
        }
Пример #5
0
        protected virtual async Task GetCompletionTask()
        {
            //waiting until some children is registered
            if (m_children.Count == 0)
            {
                LogHelper.Logger.WarnFormat("{0} still has no children. Will check again soon.", this.FullName);
                await Task.Delay(m_dataflowOptions.MonitorInterval).ConfigureAwait(false);

                if (m_children.Count == 0)
                {
                    throw new NoChildRegisteredException(this);
                }
            }

            Exception exception = null;

            try
            {
                await TaskEx.AwaitableWhenAll(() => m_children, b => b.Completion).ConfigureAwait(false);

                await TaskEx.AwaitableWhenAll(() => m_postDataflowTasks, f => f()).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                m_isFaulted = 1;
                foreach (var cts in m_ctsList)
                {
                    cts.Cancel();
                }
                exception = e;
            }
            finally
            {
                this.CleanUp(exception);

                if (exception == null)
                {
                    LogHelper.Logger.Info(string.Format("{0} completed", this.FullName));
                }
                else
                {
                    LogHelper.Logger.Info(string.Format("{0} completed with error", this.FullName));
                    throw new AggregateException(exception);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Register an external block as dependency, whose completion will trigger completion of this dataflow
        /// if this dependencies finishes as the last amony all dependencies.
        /// i.e. Completion of this dataflow will only be triggered after ALL dependencies finish.
        /// </summary>
        internal void RegisterDependency(IDataflowDependency dependency)
        {
            bool isFirstDependency = m_dependencies.IsEmpty;

            if (!ImmutableUtils.TryAddOptimistically(ref m_dependencies, dependency))
            {
                LogHelper.Logger.WarnFormat("A dependency registration is ignored by {0} as it is already a dependency: {1}", this.FullName, dependency.DisplayName);
            }

            if (isFirstDependency)
            {
                TaskEx.AwaitableWhenAll(() => m_dependencies, f => f.Completion).ContinueWith(
                    upstreamTask =>
                {
                    if (!this.CompletionTask.IsCompleted)
                    {
                        if (upstreamTask.IsFaulted)
                        {
                            this.Fault(new LinkedDataflowFailedException());
                        }
                        else if (upstreamTask.IsCanceled)
                        {
                            this.Fault(new LinkedDataflowCanceledException());
                        }
                        else
                        {
                            if (m_dependencies.Count > 1)
                            {
                                LogHelper.Logger.InfoFormat("{0} All of my dependencies are done. Completing myself.", this.FullName);
                            }
                            this.Complete();
                        }
                    }
                });
            }
            else
            {
                LogHelper.Logger.InfoFormat("{0} now has {1} dependencies. (Added {2})", this.FullName, m_dependencies.Count, dependency.DisplayName);
            }
        }
Пример #7
0
        /// <summary>
        /// Register an external block as dependency, whose completion will trigger completion of this dataflow
        /// if this dependencies finishes as the last amony all dependencies.
        /// i.e. Completion of this dataflow will only be triggered after ALL dependencies finish.
        /// </summary>
        internal void RegisterDependency(IDataflowDependency dependency)
        {
            bool isFirstDependency = m_dependencies.IsEmpty;

            m_dependencies = m_dependencies.Add(dependency);

            if (isFirstDependency)
            {
                TaskEx.AwaitableWhenAll(() => m_dependencies, f => f.Completion).ContinueWith(
                    upstreamTask =>
                {
                    if (!this.Completion.IsCompleted)
                    {
                        if (upstreamTask.IsFaulted)
                        {
                            this.Fault(new LinkedDataflowFailedException());
                        }
                        else if (upstreamTask.IsCanceled)
                        {
                            this.Fault(new LinkedDataflowCanceledException());
                        }
                        else
                        {
                            if (m_dependencies.Count > 1)
                            {
                                LogHelper.Logger.InfoFormat("{0} All of my dependencies are done. Completing myself.", this.FullName);
                            }
                            this.Complete();
                        }
                    }
                });
            }
            else
            {
                LogHelper.Logger.InfoFormat("{0} now has {1} dependencies. (Added {2})", this.FullName, m_dependencies.Count, dependency.DisplayName);
            }
        }