我注意到任务可以通过抛出OperationCanceledException
来取消。通常,可以在OperationCanceledException
constructor中传递用户友好的原因,后来成为异常消息。但是,它在任务场景中看起来并不那样。该异常使任务被取消,但最终被转换为TaskCanceledException
,原始消息被替换为通用消息。
在这个例子中是否有一种简洁的方式来说明取消原因?我看了CancellationTokenSource
,但没有看到任何选项。
class Program
{
static async Task MyAsyncMethod()
{
await Task.Delay(TimeSpan.FromSeconds(1));
throw new OperationCanceledException("My lost cancellation reason");
}
static void Main(string[] args)
{
var task = MyAsyncMethod();
try
{
task.Wait();
}
catch (AggregateException ecxeptions)
{
var exception = ecxeptions.InnerException;
Console.WriteLine(exception.GetType()); //TaskCanceledException
Console.WriteLine(exception.Message); //A task was canceled.
Console.WriteLine(task.Status); //Canceled
Console.WriteLine(task.Exception == null); //true
}
Console.Read();
}
}
答案 0 :(得分:1)
仅当您使用Task.Wait
创建一个捆绑所有内部异常的新AggregateException
时,才会发生这种情况。
如果您使用await
,则会抛出实际异常,并且会显示正确的消息。由于您无法在await
中使用Main
,因此您可以使用GetAwaiter().GetResult()
同步阻止,但仍会产生与await
相同的异常(没有聚合) :
static async Task MyAsyncMethod()
{
await Task.Delay(TimeSpan.FromSeconds(1));
throw new TaskCanceledException("My lost cancellation reason");
}
static void Main()
{
var task = MyAsyncMethod();
try
{
task.GetAwaiter().GetResult();
}
catch (TaskCanceledException exception)
{
Console.WriteLine(exception.GetType()); // TaskCanceledException
Console.WriteLine(exception.Message); // My lost cancellation reason
Console.WriteLine(task.Status); // Canceled
Console.WriteLine(task.Exception == null); // true
}
Console.Read();
}