I play with cancelation token, and I would like to understand how this works. I have two async methods(in my example two but in theory I can have 100). I want to cancel work in all async methods if one of them throws an exception.
My idea is to cancel token in exception where all methods are called. When a token is canceled I would expect that other method stop working, but this is not happening.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace CancelationTest
{
class Program
{
static void Main(string[] args)
{
new Test();
Console.ReadKey();
}
}
public class Test
{
public Test()
{
Task.Run(() => MainAsync());
}
public static async Task MainAsync()
{
var cancellationTokenSource = new CancellationTokenSource();
try
{
var firstTask = FirstAsync(cancellationTokenSource.Token);
var secondTask = SecondAsync(cancellationTokenSource.Token);
Thread.Sleep(50);
Console.WriteLine("Begin");
await secondTask;
Console.WriteLine("hello");
await firstTask;
Console.WriteLine("world");
Console.ReadKey();
}
catch (OperationCanceledException e)
{
Console.WriteLine("Main OperationCanceledException cancel");
}
catch (Exception e)
{
Console.WriteLine("Main Exception + Cancel");
cancellationTokenSource.Cancel();
}
}
public static async Task FirstAsync(CancellationToken c)
{
c.ThrowIfCancellationRequested();
await Task.Delay(1000, c);
Console.WriteLine("Exception in first call");
throw new NotImplementedException("Exception in first call");
}
public static async Task SecondAsync(CancellationToken c)
{
c.ThrowIfCancellationRequested();
await Task.Delay(15000, c);
Console.WriteLine("SecondAsync is finished");
}
}
}
The second method finish work and delay task for 15 seconds even when the first method throws an exception.
What is result:
Begin
Exception in the first call
SecondAsync is finished
hello
Main Exception + Cancel
I would expect that secondAsync stop delay and throw OperationCancelException. I would expect this result:
Begin
Exception in first call
Main Exception + Cancel
Main OperationCanceledException cancel
Where am I making mistake? Why method SecondAsync is fully executed and doesn't throw an exception? And if I change the order of SecondAsync and FirstAsync than Second method stop to delay when the token is canceled and throw an exception.