2015-11-04 23 views
1

我注意到任務可以通過拋出OperationCanceledException來取消自己。通常情況下,人們可以通過用戶友好的原因在後來成爲異常消息的OperationCanceledExceptionconstructor中。但是,在任務場景中它看起來並不如此。異常使得任務被取消,但最終被翻譯成TaskCanceledException,原始消息被替換爲通用消息。使用OperationCanceledException自行取消任務

在這個例子中是否有一個簡潔的方式來說明取消原因?我看着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(); 
    } 
    } 

回答

1

這僅當您使用Task.Wait這將創建一個新的AggregateException捆綁所有的內部異常情況發生。

如果您使用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(); 
}