TransformBlock never completes

前端 未结 3 881
再見小時候
再見小時候 2021-01-11 10:42

I\'m trying to wrap my head around \"completion\" in TPL Dataflow blocks. In particular, the TransformBlock doesn\'t seem to ever complete. Why?

Sample

3条回答
  •  抹茶落季
    2021-01-11 11:27

    I think I understand it now. An instance of TransformBlock is not considered "complete" until the following conditions are met:

    1. TransformBlock.Complete() has been called
    2. InputCount == 0 – the block has applied its transformation to every incoming element
    3. OutputCount == 0 – all transformed elements have left the output buffer

    In 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);
                }
            }
        }
    }
    

提交回复
热议问题