问题
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>());
来源:https://stackoverflow.com/questions/47455192/tpl-dataflow-never-completes-when-using-a-predicate