using System.Threading.Tasks;
while (true) Console.ReadKey();
public static async Task Use()
var coordinator = new TaskCoordinator();
coordinator.Register(Task1);
async Task Task1(TaskCoordinator.Handle handle)
throw new NotImplementedException();
Program.Print("Task 1 Finished");
coordinator.Register(Task2);
async Task Task2(TaskCoordinator.Handle handle)
handle.ThrowIfCancellationRequested();
Program.Print("Task 2 Finished");
coordinator.Register(Task3);
async Task Task3(TaskCoordinator.Handle handle)
handle.ThrowIfCancellationRequested();
Program.Print("Task 3 Finished");
await coordinator.Await();
public static void Print(object target) => Console.WriteLine(target);
CancellationTokenSource CancellationSource;
public CancellationToken CancellationToken => CancellationSource.Token;
TaskCompletionSource<bool> StartSource;
TaskCompletionSource<bool> ProcessingSource;
volatile int HandleCount;
public Handle CreateHandle()
Interlocked.Increment(ref HandleCount);
public async Task Await()
StartSource.SetResult(true);
await ProcessingSource.Task;
if (Interlocked.Decrement(ref HandleCount) is not 0)
ProcessingSource.TrySetResult(true);
void FailHandle(Exception exception)
Program.Print("Previous Line");
var output = ProcessingSource.TrySetException(exception);
Program.Print("Next Line");
CancellationSource.Cancel();
Program.Print("Catch Exception");
Program.Print("Finally Block");
public void Register(Func<Handle, Task> function)
var handle = CreateHandle();
var task = function(handle);
public async void Register(Task task)
catch (OperationCanceledException) when (CancellationToken.IsCancellationRequested)
CancellationSource = new CancellationTokenSource();
ProcessingSource = new();
readonly TaskCoordinator Coordinator;
public CancellationToken CancellationToken => Coordinator.CancellationToken;
public bool IsCancellationRequested => CancellationToken.IsCancellationRequested;
public void ThrowIfCancellationRequested() => CancellationToken.ThrowIfCancellationRequested();
var exception = new Exception($"Handle Failed");
public void Fail(Exception exception)
Coordinator.FailHandle(exception);
public Handle(TaskCoordinator Coordinator)
this.Coordinator = Coordinator;