I\'m trying to wrap my head around \"completion\" in TPL Dataflow blocks. In particular, the TransformBlock
doesn\'t seem to ever complete. Why?
I think I understand it now. An instance of TransformBlock
is not considered "complete" until the following conditions are met:
TransformBlock.Complete()
has been calledInputCount == 0
– the block has applied its transformation to every incoming elementOutputCount == 0
– all transformed elements have left the output bufferIn my program, there is no target block that is linked to the source TransformBlock
, so the source block never gets to flush its output buffer.
As a workaround, I added a second BufferBlock
that is used to store transformed elements.
static void Main(string[] args)
{
var inputBufferBlock = new BufferBlock();
var calculatorBlock = new TransformBlock(i =>
{
Console.WriteLine("Calculating {0}²", i);
return (int)Math.Pow(i, 2);
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 8 });
var outputBufferBlock = new BufferBlock();
using (inputBufferBlock.LinkTo(calculatorBlock, new DataflowLinkOptions { PropagateCompletion = true }))
using (calculatorBlock.LinkTo(outputBufferBlock, new DataflowLinkOptions { PropagateCompletion = true }))
{
foreach (var number in Enumerable.Range(1, 1000))
{
inputBufferBlock.Post(number);
}
inputBufferBlock.Complete();
calculatorBlock.Completion.Wait();
IList results;
if (outputBufferBlock.TryReceiveAll(out results))
{
foreach (var result in results)
{
Console.WriteLine("x² = {0}", result);
}
}
}
}