繁体   English   中英

使用OperationCanceledException自取消任务

[英]Self cancelling the task with OperationCanceledException

我注意到任务可以通过抛出OperationCanceledException取消自身。 通常,可以在OperationCanceledException 构造函数中传递一个用户友好的原因,该构造函数随后成为异常消息。 但是,在任务场景中看起来不是那样。 该异常使任务被取消,但最终被转换为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();
    }
  }

仅当您使用Task.Wait创建一个新的AggregateException并将所有内部异常捆绑Task.Wait ,才会发生这种情况。

如果使用await ,则会抛出实际的异常,并会显示正确的消息。 由于您无法在Main使用await ,因此可以使用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();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM