TPL Dataflow never completes when using a predicate
Asked Answered
K

1

5

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
Kloof answered 23/11, 2017 at 12:5 Comment(0)
S
10

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>());
Standoffish answered 23/11, 2017 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.