如何更好地理解来自“异步处理多个异常”的代码/语句文章? [英] How to better understand the code/statements from "Async - Handling multiple Exceptions" article?
问题描述
运行以下C#控制台应用程序
Running the following C# console app
class Program
{ static void Main(string[] args)
{ Tst();
Console.ReadLine();
}
async static Task Tst()
{
try
{
await Task.Factory.StartNew
(() =>
{
Task.Factory.StartNew
(() =>
{ throw new NullReferenceException(); }
, TaskCreationOptions.AttachedToParent
);
Task.Factory.StartNew
( () =>
{ throw new ArgumentException(); }
,TaskCreationOptions.AttachedToParent
);
}
);
}
catch (AggregateException ex)
{
// this catch will never be target
Console.WriteLine("** {0} **", ex.GetType().Name);
//****** Update1 - Start of Added code
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine(exc.GetType().Name);
}
//****** Update1 - End of Added code
}
catch (Exception ex)
{
Console.WriteLine("## {0} ##", ex.GetType().Name);
}
}
产生输出:
** AggregateException **
但是,上面的代码是从异步处理多个异常博客文章,它告诉它:
Though, the code above is reproducing the first snippet from "Async - Handling multiple Exceptions" blog article, which tells about it :
以下代码将捕获单个NullReferenceException或
ArgumentException异常(AggregateException将被忽略)
the following code will catch a single NullReferenceException or ArgumentException exception (the AggregateException will be ignored)
问题在哪里? / p>
Where is the problem:
- 文章错了?
哪些代码/语句和如何更改才能正确理解? - 我在复制文章的第一个代码段时发生错误?
- 这是由于.NET 4.0 / VS2010中的错误Async CTP扩展,我在使用?
Update1(响应 svick的答案)
添加代码后
Update1 (in response to svick's answer)
Upon adding the code
//****** Update1 - Start of Added code
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine(exc.GetType().Name);
}
//****** Update1 - End of Added code
生成的输出是:
** AggregateException **
NullReferenceException
所以,同样评论Matt Smith :
<被捕获的code> AggregateException 只包含抛出的
异常之一($ code> NullReferenceException 或
ArgumentException
取决于孩子的执行顺序
任务)
the
AggregateException
that is caught, contains only one of the exceptions that was thrown (either theNullReferenceException
or theArgumentException
depending on the order of execution of the child Tasks)
最有可能的是,文章仍然是正确的,或者至少非常有用。我只需要了解如何更好地阅读/理解/使用它
Most probably, the article is still correct or, at least, very useful. I just need to understand how to better read/understand/use it
执行svick的代码:
Executing svick's code:
internal class Program
{
private static void Main(string[] args)
{
Tst();
Console.ReadLine();
}
private static async Task Tst()
{
try
{
await TaskEx.WhenAll
(
Task.Factory.StartNew
(() =>
{ throw new NullReferenceException(); }
//, TaskCreationOptions.AttachedToParent
),
Task.Factory.StartNew
(() =>
{ throw new ArgumentException(); }
//,TaskCreationOptions.AttachedToParent
)
);
}
catch (AggregateException ex)
{
// this catch will never be target
Console.WriteLine("** {0} **", ex.GetType().Name);
//****** Update1 - Start of Added code
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine("==="+exc.GetType().Name);
}
//****** Update1 - End of Added code
}
catch (Exception ex)
{
Console.WriteLine("## {0} ##", ex.GetType().Name);
}
}
}
产生:
## NullReferenceException ##
输出。
为什么不会生成或捕获 AggregateException
?
Why isn't AggregateException
produced or caught?
推荐答案
文章错误。当您运行代码时,等待
ed 任务
包含一个如下所示的异常:
The article is wrong. When you run your code, the await
ed Task
contains an exception that looks something like this:
AggregateException
AggregateException
NullReferenceException
AggregateException
ArgumentException
什么等待
(或更具体地说, TaskAwaiter.GetResult()
)这里是否需要外部 AggregateException
并重新抛出其第一个小孩异常。在这里,这是另一个 AggregateException
,所以这是抛出的。
What await
(or, more specifically, TaskAwaiter.GetResult()
) does here is that it takes the outer AggregateException
and rethrows its first child exception. Here, that's another AggregateException
, so that's what is thrown.
代码示例,其中一个任务
有多个异常,其中一个异常是直接重新抛出,在 await
将使用 Task.WhenAll() / code>而不是
AttachedToParent
:
Example of code where a Task
has multiple exceptions and one of them is directly rethrown after await
would be to use Task.WhenAll()
instead of AttachedToParent
:
try
{
await Task.WhenAll(
Task.Factory.StartNew(() => { throw new NullReferenceException(); }),
Task.Factory.StartNew(() => { throw new ArgumentException(); }));
}
catch (AggregateException ex)
{
// this catch will never be target
Console.WriteLine("** {0} **", ex.GetType().Name);
}
catch (Exception ex)
{
Console.WriteLine("## {0} ##", ex.GetType().Name);
}
这篇关于如何更好地理解来自“异步处理多个异常”的代码/语句文章?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!