-->

TPL Dataflow never completes when using a predicat

2019-08-10 16:05发布

问题:

I have the following TPL Dataflow that never completes when using a predicate to filter the items passed from the TransformBlock to the ActionBlock.

If the predicate returns false for any of the items, then the dataflow hangs.

Please can someone offer some insight as to what's happening and how to resolve this?

// define blocks 
var getBlock = new TransformBlock<int, int>(i =>
{
    Console.WriteLine($"getBlock: {i}");

    return ++i;
});

var writeBlock = new ActionBlock<int>(i =>
{
    Console.WriteLine($"writeBlock: {i}");
});

// link blocks
getBlock.LinkTo(writeBlock, new DataflowLinkOptions
{
    PropagateCompletion = true
}, i => i == 12); // <-- this predicate prevents the completion of writeBlock

// push to block 
var items = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (var i in items)
{
    getBlock.Post(i); 
}

// wait for all operations to complete
getBlock.Complete();
await writeBlock.Completion; // <-- application hangs here

回答1:

The getBlock is not completing because the items posted to it have nowhere to go. If you have a predicate add a null target so that any items that don't match have a place to exit the pipeline.

getBlock.LinkTo(writeBlock, new DataflowLinkOptions
{
    PropagateCompletion = true
}, i => i == 12)
getBlock.LinkTo(DataflowBlock.NullTarget<int>());