Why this program stop running? Await exception handling and canceling issue

72 Views Asked by At

I was given a task to write asynchronous console application, and faced problem with "await" exception handling. The task is that I need to perform some specific calculations asynchronously, and be able to cancel that calculation(while it's running).

So, I have a code like this:

       public static async void CalculateSomeValue()
       {
           bool isRunning = true;
           while (isRunning)
           {
               using CancellationTokenSource cts = new CancellationTokenSource();
               CancellationToken token = cts.Token;

               Console.Write("Start of calculation:\nInput natural number = ");
               long number = long.Parse(Console.ReadLine());
               Task<double> task = CalculationAsync(number, token);

               Console.WriteLine("To cancel calculation press button 'Enter'. To continue press any other key.");
               if (Console.ReadKey().Key == ConsoleKey.Enter)
               {
                   cts.Cancel();
               }

               try
               {
                   await task;
               }
               catch
               {
                   Console.WriteLine("Task execution is corrupted. More info:");
               }
               finally
               {
                   Console.WriteLine(CorrespondingMessage(task));
               }

               Console.WriteLine("Continue?");
               if (Console.ReadKey().Key == ConsoleKey.Escape)
               {
                   isRunning = false;
               }

               Console.Clear();
           }
       }

And code for async method:

       private static async Task<double> Calculation(long number, CancellationToken token)
       {
           token.ThrowIfCancellationRequested();
           return await Task.Factory.StartNew(() => SumUntil(number, token));

           static double SumUntil(long number, CancellationToken token)
           {
               if (number <= 0)
               {
                   throw new ArgumentException($"{nameof(number)} is invalid.");
               }

               double result = 0;
               for (double summand = 1; summand <= number; summand++)
               {
                   token.ThrowIfCancellationRequested();
                   result += 1 / summand;
               }

               return result;
           }
       }

Corresponding message is responsible for printing the result(meaning it prints whether task was cancelled, there was an exception, or task was completed successfully and so on).

So, when I cancel the task, or just put invalid values(which causes ArgumentException and then AggregateException), my program(in some runs) just exits, but when I switch to task.Wait() in try..catch constuction and remove "async" keyword in method signature, it works fine in all runs. I can't figure out the problem, it is some debugging feature for CLR thread pool, or I wrote something wrong? Appreciate any links or literature.

0

There are 0 best solutions below