-1

I have this code snippet:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });
    var countBytes = new TransformBlock<int, int>(
        new Func<int, int>((x)=> { return 2 * x; }));
    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Completion.ContinueWith(delegate { printResult.Complete(); });
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.ReadKey();
}

I expected that the TransformBlock code of

return 2*x

will run, and then print the result, but in fact, nothing is printed. I set a break point inside the

printResult

function object on the Console.WriteLine but it was not stepped in.

Why nothing is printed, where did I get wrong and how to fix it?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 1
    You haven't posted anything to either block – Panagiotis Kanavos Mar 11 '20 at 12:32
  • 1
    And the line `countBytes.Completion.ContinueWith(delegate { printResult.Complete(); });` does what `PropagateCompletion = true` already does – Panagiotis Kanavos Mar 11 '20 at 12:34
  • 1
    You should add `countBytes.Post(123);` before calling `countBytes.Complete();` – Panagiotis Kanavos Mar 11 '20 at 12:35
  • The code block seems to be copied right from here: https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-perform-action-when-a-dataflow-block-receives-data and it is therefore interesting that the following line is missing: countBytes.Post(tempFile); – Oguz Ozgul Mar 11 '20 at 12:40

1 Answers1

1

You are missing the setting to tell countBytes to propagate completion to the linked block (trying to use a ContinueWith() to complete a linked block is the wrong way to do this).

Also, if you don't post anything to the pipeline, there won't be any output.

Try this instead:

static void Main(string[] args)
{
    var printResult = new ActionBlock<int>(x =>
    {
        Console.WriteLine(x);
    });

    var countBytes = new TransformBlock<int, int>(new Func<int, int>((x) => { return 2 * x; }));

    countBytes.LinkTo(printResult, new DataflowLinkOptions { PropagateCompletion = true });
    countBytes.Post(1);
    countBytes.Completion.ContinueWith(task => Console.WriteLine("countBytes has completed"));
    printResult.Completion.ContinueWith(task => Console.WriteLine("printResult has completed"));
    countBytes.Complete();
    printResult.Completion.Wait();
    Console.WriteLine("Done");
    Console.ReadLine();
}

If you run that, the output is:

2
countBytes has completed
Done
printResult has completed

(Note how "printResult has completed" is output after "Done". This is because the continuation is scheduled AFTER printResult.Completion is signalled.)

If you comment out the new DataflowLinkOptions { PropagateCompletion = true } like so:

countBytes.LinkTo(printResult /*, new DataflowLinkOptions { PropagateCompletion = true } */);

then the output will be:

2
countBytes has completed

Note that "Done" is not printed, because printResult.Completion.Wait() never returns if the completion is not propagated to that block.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276