0

我的任务是编写异步控制台应用程序,并面临“等待”异常处理的问题。任务是我需要异步执行一些特定的计算,并且能够取消该计算(在它运行时)。

所以,我有这样的代码:

       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();
           }
       }

以及异步方法的代码:

       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;
           }
       }

相应的消息负责打印结果(即打印任务是否被取消、是否出现异常、任务是否成功完成等)。

所以,当我取消任务,或者只是输入无效值(这会导致 ArgumentException 然后是 AggregateException),我的程序(在某些运行中)只是退出,但是当我切换到task.Wait()try..catch 构造并删除“async”关键字时方法签名,它在所有运行中都能正常工作。 我想不通,是CLR线程池的一些调试功能,还是我写错了?欣赏任何链接或文献。

4

0 回答 0