C# InnerException в AggregateExpression

У меня есть этот код, как показано ниже, чтобы захватить исключение из задач, созданных с помощью TaskFactory и Task.Run. Если я использую TaskFactory, я могу проверить Исключение, сгенерированное из предыдущей задачи в задаче Continued, без необходимости использовать метод Task.WaitAll. Если я использую Task.Run, задача Continued не будет выполняться, пока я явно не дождусь завершения дочерних задач. Какой флаг в TaskFactory.StartNew изменил это поведение?

Кроме того, в чем разница между InnerException и InnerException в классе AggregateException? InnerExceptions возвращает мне доступную только для чтения коллекцию всех исключений, создаваемых дочерними задачами. InnerException возвращает AggregateExcpetion исключения, выданного только одной дочерней задачей.

//Use Factory
TaskCreationOptions atp = TaskCreationOptions.AttachedToParent;
Task.Factory.StartNew(() =>
{
    Task.Factory.StartNew (() => { throw null; }, atp);
    Task.Factory.StartNew (() => { throw new NullReferenceException();}, atp);
    Task.Factory.StartNew (() => { throw new Exception("Test"); }, atp);
})
.ContinueWith (p => p.Exception.Dump(),TaskContinuationOptions.OnlyOnFaulted);

//Use Task.Run
Task.Run(()=>
{
    TaskCreationOptions op = TaskCreationOptions.AttachedToParent;
    var t1 = Task.Factory.StartNew(()=> {throw null;}, op);
    var t2 = Task.Factory.StartNew(()=> {throw new NullReferenceException();}, op);
    var t3 = Task.Factory.StartNew(()=> {throw new Exception("Test");}, op);

    //This will trigger the continued task
    //Task.WaitAll(new Task[]{t1,t2,t3}); 
}).ContinueWith(task => {task.Exception.Dump();}, TaskContinuationOptions.OnlyOnFaulted);

1 ответ

Решение
  • InnerException является собственностью Exception с возвратами "исключение, вызвавшее это исключение".
  • InnerExceptions это свойство, уникальное для AggregateException, Благодаря своему дизайну, совокупное исключение может содержать несколько "вызывающих" исключений.

Как собственность InnerException наследуется, имеет смысл, что он возвращает первое исключение из InnerExceptions,

Чтобы ответить на ваш другой вопрос о поведении вашего примера кода, разница заключается в TaskCreationOptions по умолчанию для Task.Run, По умолчанию TaskCreationOptions.DenyChildAttach, Вы можете прочитать больше об этом в этом блоге.

Другие вопросы по тегам