Рассмотрим следующий фрагмент кода:
CancellationTokenSource cts0 = new CancellationTokenSource(), cts1 = new CancellationTokenSource();
try
{
var task = Task.Run(() => { throw new OperationCanceledException("123", cts0.Token); }, cts1.Token);
task.Wait();
}
catch (AggregateException ae) { Console.WriteLine(ae.InnerException); }
Из-за MSDN задача должна быть в состоянии Faulted, потому что токен не совпадает с токеном исключения ( а также IsCancellationRequested false):
Если свойство token IsCancellationRequested возвращает false или если токен исключения не соответствует токену задачи, исключение OperationCanceledException рассматривается как обычное исключение, в результате чего задача переходит к состоянию Faulted.
Когда я запускаю этот код в консольном приложении с использованием .NET 4.5.2, я получаю задачу в состоянии Canceled (суммарное исключение содержит неизвестный TaskCanceledExeption, а не оригинал). И вся информация об исходном исключении теряется (сообщение, внутреннее исключение, пользовательские данные).
Я также заметил, что поведение Task.Wait отличается от await task в случае OperationCanceledException.
try { Task.Run(() => { throw new InvalidOperationException("123"); }).Wait(); } // 1
catch (AggregateException ae) { Console.WriteLine(ae.InnerException); }
try { await Task.Run(() => { throw new InvalidOperationException("123"); }); } // 2
catch (InvalidOperationException ex) { Console.WriteLine(ex); }
try { Task.Run(() => { throw new OperationCanceledException("123"); }).Wait(); } // 3
catch (AggregateException ae) { Console.WriteLine(ae.InnerException); }
try { await Task.Run(() => { throw new OperationCanceledException("123"); }); } // 4
catch (OperationCanceledException ex) { Console.WriteLine(ex); }
Случаи 1 и 2 производят почти одинаковый результат (отличаются только StackTrace), но когда я изменяю исключение на OperationCanceledException, то получаю очень разные результаты: неизвестный TaskCanceledException в случае 3 > без исходных данных и ожидаемых OpeartionCanceledException в случае 4 со всеми исходными данными (сообщение и т.д.).
Итак, вопрос в том, содержит ли MSDN неправильную информацию? Или это ошибка в .NET? Или, может быть, я просто ничего не понимаю?
