I don't really understand this. In my code below, run as-is, the exception thrown by token.ThrowIfCancellationRequested() is not being sent back to where Main is using .Wait(), and is instead thrown on the spot with the stacktrace not really knowing where it happened other than "A task was cancelled". However if I remove the async keyword and remove the try catch block with the await Task.Delay(), it does get sent back to .Wait() in main and is caught there.
Am I doing something wrong, or how exactly do I get both the exception thrown by await Task.Delay() and token.ThrowIfCancellationRequested() to both bubble up to .Wait()?
static void Main(string[] args)
{
var t = new CancellationTokenSource();
var task = Task.Factory.StartNew((x) => Monitor(t.Token), t.Token, TaskCreationOptions.LongRunning);
while (true)
{
if (Console.ReadLine() == "cancel")
{
t.Cancel();
try
{
task.Wait();
}
catch(AggregateException)
{
Console.WriteLine("Exception via task.Wait()");
}
Console.WriteLine("Cancelled");
}
}
}
static async void Monitor(CancellationToken token)
{
while(true)
{
for(int i = 0; i < 5; i++)
{
// If the async in the method signature, this does not send the exception to .Wait();
token.ThrowIfCancellationRequested();
// Do Work
Thread.Sleep(2000);
}
// Wait 10 seconds before doing work again.
// When this try block is removed, and the async is taken out of the method signature,
// token.ThrowIfCancellationRequested() properly sends the exception to .Wait()
try
{
await Task.Delay(10000, token);
}
catch(TaskCanceledException)
{
Console.WriteLine("Exception from Delay()");
return;
}
}
}