CSharp · Console
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
static class Program
{
public static void Main()
{
var cts = new CancellationTokenSource();
cts.Token.Register(() => Console.WriteLine("Token Canceled"));
var options = new ExecutionDataflowBlockOptions()
{
BoundedCapacity = 1,
CancellationToken = cts.Token,
};
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}");
return item;
}, options);
var block3 = new ActionBlock<char>(item =>
{
Console.WriteLine($"Block-3 processing {item}");
Thread.Sleep(100);
throw new Exception();
}, options);
block1.LinkTo(block2, new() { PropagateCompletion = true });
block2.LinkTo(block3, new() { PropagateCompletion = true });
block1.OnErrorCancel(cts);
block2.OnErrorCancel(cts);
block3.OnErrorCancel(cts);
block1.Post('A');
block1.Post('B');
block1.Post('C');
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 OnErrorCancel(this IDataflowBlock block, CancellationTokenSource cts)
{
try { await block.Completion.ConfigureAwait(false); } catch { }
if (block.Completion.IsFaulted) cts.Cancel();
}
}