1

Given this code:

s_Batch = new BatchBlock<PerformanceRecord>(500);
s_Action = new ActionBlock<PerformanceRecord[]>(a => SendToDatabase(a));
s_Batch.LinkTo(s_Action);

When I'm done do I need to call Complete() on each block? Or will completing s_Batch trigger a complete in the blocks linked to it?

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Jonathan Allen
  • 68,373
  • 70
  • 259
  • 447
  • possible duplicate of [TPL Dataflow, guarantee completion only when ALL source data blocks completed](http://stackoverflow.com/questions/13510094/tpl-dataflow-guarantee-completion-only-when-all-source-data-blocks-completed) – Jonathan Allen Nov 07 '14 at 06:09
  • Does the above answer satisfy your need? – Yuval Itzchakov Nov 07 '14 at 06:55

2 Answers2

6

As your code stands now, you need to call Complete on all blocks individually:

s_Batch.Complete();
await s_Batch.Completion;

s_Action.Complete();
await s_Action.Completion;

You could however use DataflowLinkOptions while linking the blocks to request completion propagation:

s_Batch.LinkTo(s_Action, new DataflowLinkOptions {PropagateCompletion = true});
s_Batch.Complete();
await s_Batch.Completion;

This will propagate both completion and faulting notification to the linked target block (i.e. s_Action).

i3arnon
  • 113,022
  • 33
  • 324
  • 344
1

I like l3arnon's answer actually since it is the most concise.

This is something else I have done/seen with TPL blocks which also works.

s_Batch.Completion.ContinueWith( t => 
    { 
        if(t.IsFaulted) 
            ((IDataFlowBlock)s_Action).Fault(t.Exception);
        else
            s_Action.Complete();
    });
s_Batch.Complete();
s_Action.Completion.Wait();

Downside is that you will need to repeat this pattern for each linked block so you end up repeating yourself quite a bit.

tyh
  • 977
  • 1
  • 8
  • 22