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
, Вы можете прочитать больше об этом в этом блоге.