我的任务是编写异步控制台应用程序,并面临“等待”异常处理的问题。任务是我需要异步执行一些特定的计算,并且能够取消该计算(在它运行时)。
所以,我有这样的代码:
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线程池的一些调试功能,还是我写错了?欣赏任何链接或文献。