I noticed I was not getting logging messages in my app when some new async code was throwing an error. I have an app that kicks off a small number of indefinitely-running async tasks. Each of them runs their own while(true)
loop.
I have some error logging in a couple places, but I noticed that the exception propagation stops when it gets to the bounds of the infinite while
loop within the Task. Originally, my logging was only outside that loop, and while that particular Task stopped running, the error was not getting logged.
Here is a sample program that shows the same behavior - if I remove the while(true)
so that the Track()
method only runs once through, then the exception bubbles up to the RunAsync()
method, and the app crashes (which is what I would want). But with the while loop in there, it continues to run the loop for number 2, and number 1 dies a silent death.
I understand that unawaited Tasks can get their exceptions swallowed, but I believe I am awaiting everything that needs awaiting - please correct me if I'm wrong.
static void Main(string[] args)
{
Console.WriteLine("Starting up");
RunAsync().GetAwaiter().GetResult();
Console.WriteLine("Shutting down");
}
private static async Task RunAsync()
{
try
{
Console.WriteLine("In RunAsync");
List<int> trackers = new List<int> { 1, 2 };
await Task.WhenAll(trackers.Select(tracker => Track(tracker)));
}
catch (Exception e)
{
Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff} => Error in RunAsync\n{e.StackTrace}");
throw;
}
}
private static async Task Track(int number)
{
Console.WriteLine($"Starting tracker for {number}");
while (true) // This causes the exception to not propagate up
{
Console.WriteLine($"In here for number {number}");
if (number == 1)
{
throw new Exception("Oops! Number 1 does not work");
}
await Task.Delay(1000);
}
}
Is there something I should be doing differently to handle the exceptions that may occur within that loop?
Here is the output with the loop in place
Starting up
In RunAsync
Starting tracker for 1
In here for number 1
Starting tracker for 2
In here for number 2
In here for number 2
In here for number 2
and here it is without the while loop
Starting up
In RunAsync
Starting tracker for 1
In here for number 1
Starting tracker for 2
In here for number 2
16:58:34.916 => Error in RunAsync
at Program.<Track>d__2.MoveNext() in Program.cs:line 48
--- End of stack trace from previous location where exception was thrown ---