TransformBlock never completes

前端 未结 3 903
再見小時候
再見小時候 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:28

    The reason your pipeline hangs is that both BufferBlock and TransformBlock evidently don't complete until they emptied themselves of items (I guess that the desired behavior of IPropagatorBlocks although I haven't found documentation on it).

    This can be verified with a more minimal example:

    var bufferBlock = new BufferBlock();
    bufferBlock.Post(0);
    bufferBlock.Complete();
    bufferBlock.Completion.Wait();
    

    This blocks indefinitely unless you add bufferBlock.Receive(); before completing.

    If you remove the items from your pipeline before blocking by either your TryReceiveAll code block, connecting another ActionBlock to the pipeline, converting your TransformBlock to an ActionBlock or any other way this will no longer block.


    About your specific solution, it seems that you don't need a BufferBlock or TransformBlock at all since blocks have an input queue for themselves and you don't use the return value of the TransformBlock. This could be achieved with just an ActionBlock:

    var block = new ActionBlock(
        i =>
        {
            Console.WriteLine("Calculating {0}²", i);
            Console.WriteLine("x² = {0}", (int)Math.Pow(i, 2));
        },
        new ExecutionDataflowBlockOptions {MaxDegreeOfParallelism = 8});
    foreach (var number in Enumerable.Range(1, 1000))
    {
        block.Post(number);
    }
    block.Complete();
    block.Completion.Wait();
    

提交回复
热议问题