.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

static class Program
{
    public static void Main()
    {
        var block1 = new TransformBlock<char, char>(item =>
        {
            Console.WriteLine($"Block-1 processing {item}");
            return item;
        });

        var block2 = new TransformBlock<char, char>(item =>
        {
            Console.WriteLine($"Block-2 processing {item}");
            Thread.Sleep(200);
            return item;
        });

        var block3 = new ActionBlock<char>(item =>
        {
            Console.WriteLine($"Block-3 processing {item}");
            Thread.Sleep(100);
            throw new Exception();
        });

        block1.LinkTo(block2, new() { PropagateCompletion = true });
        block2.PropagateFailure(block1);

        block2.LinkTo(block3, new() { PropagateCompletion = true });
        block3.PropagateFailure(block2);

        block1.Post('A');
        block1.Post('B');
        block1.Complete();

        Task whenAll = Task.WhenAll(block1.Completion, block2.Completion, block3.Completion);
        try { whenAll.Wait(1000); } catch { }
        Console.WriteLine("Task.WhenAll " + (whenAll.IsCompleted ? "Completed" : "Timed-out"));
    }
	
    static async void PropagateFailure(this IDataflowBlock block1, IDataflowBlock block2)
    {
        try { await block1.Completion.ConfigureAwait(false); } catch { }
        if (block1.Completion.IsFaulted) block2.Fault(block1.Completion.Exception);
    }
}
;