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); }
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); }
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); }
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(); }
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); } } }
/// <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); } }
/// <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); } }