【发布时间】:2013-05-12 23:32:56
【问题描述】:
重用稍作修改的代码from this answer,如何修改才能实现@svick's advice:
但是如果您将任务保存到变量中并调用 task.Exception.Flatten(),这将返回两个异常
?
//C# console app
class Program
{
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
async static Task Test()
{
Task containingTask, nullRefTask, argTask;
try
{
containingTask = Task.Factory.StartNew
(() =>
{
nullRefTask = Task.Factory.StartNew(() =>
{
throw new NullReferenceException();
}
, TaskCreationOptions.AttachedToParent);
argTask = Task.Factory.StartNew(() =>
{
throw new ArgumentException();
}
, TaskCreationOptions.AttachedToParent);
}
);
await containingTask;
foreach(Exception ex in containingTask.Exception
.Flatten().InnerExceptions)
//Possible 'System.NullReferenceException'
{ //never entered
Console.WriteLine("@@@@@"+ex.GetType().Name);
}
}//try
catch (AggregateException ex)
{
Console.WriteLine("** {0} **", ex.GetType().Name);
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine("$$$$$$"+exc.GetType().Name);
}
//foreach (Exception exxx in containingTask.Exception.Flatten().InnerExceptions)
//Use of unassigned local variable 'containingTask'
}
//foreach (Exception exxx in containingTask.Exception.Flatten().InnerExceptions)
////Use of unassigned local variable 'containingTask'
}
}
当我尝试使用或不使用try-/catch-blocks 访问containingTask.Exception.Flatten().InnerExceptions 时,在try-、catch-blocks 内外都会产生错误:
Use of unassigned local variable 'containingTask'
或
Possible 'System.NullReferenceException'
如何从两个子任务中查看/获取两个异常?
更新:
这部分已从问题中删除,因为在更正错字后,代码会产生预期的结果
变体 #2(C# 控制台应用程序):
尝试从"Async - Handling multiple Exceptions" 重现“解决方法”以查看所有子任务的所有异常:
class Program
{
static void Main(string[] args)
{
Tst();
Console.ReadLine();
}
async static Task Tst()
{
try
{
Task t= Task.Factory.StartNew
(
() =>
{
Task.Factory.StartNew
(
() =>
{ throw new NullReferenceException(); }
,TaskCreationOptions.AttachedToParent
);
Task.Factory.StartNew
(
() =>
{ throw new ArgumentException(); }
, TaskCreationOptions.AttachedToParent
);
}
);
await t.ContinueWith
(
tsk =>
{
if (tsk.Exception != null)
throw tsk.Exception;
}
);
}
catch (AggregateException ex)
{
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine("** {0} **", exc.GetType().Name);
}
}
catch (Exception ex)
{
Console.WriteLine("## {0} ##", ex.GetType().Name);
}
}
}
【问题讨论】:
-
第一个
AggregateException(来自原始任务)被包裹在第二个AggregateException(来自后续任务)中,因此您实际上需要调用Flatten()两次才能进入内部异常你想要的。 -
抱歉,我删除了 Variant2。有一个愚蠢的错字。改正后Variant2开始输出预期结果
标签: c# exception-handling task-parallel-library async-await c#-5.0