如何更好地理解code /距离报表和QUOT;异步 - 处理多个异常"文章? [英] 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 **
虽然,code以上再现来自<一个第一片段href=\"http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/12/10/async-handling-multiple-exceptions.aspx\"相对=nofollow>异步 - 处理多个异常博客文章,其中讲述的:
Though, the code above is reproducing the first snippet from "Async - Handling multiple Exceptions" blog article, which tells about it :
以下code将抓到一个NullReferenceException异常或
ArgumentException异常(该AggregateException将被忽略)
the following code will catch a single NullReferenceException or ArgumentException exception (the AggregateException will be ignored)
问题出在哪里:
- 的文章是错的?结果
其中code /报表,以及如何才能正确地理解它改变? - 我再现文章的第一code段犯了一个错误?
- 这是由于在.NET 4.0 / VS2010异步CTP扩展中的错误,我用的?
完成投入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
所以,也<一个href=\"http://stackoverflow.com/questions/16571791/how-to-better-understand-the-$c$c-statements-from-async-handling-multiple-exc#comment23813945_16572968\">commented马特·史密斯:
在 AggregateException
被抓,只包含之一
被抛出的异常(无论是的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的code:
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?
推荐答案
这篇文章是错误的。当您运行code时,的await
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
什么等待
(或,更具体地,<一href=\"http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.taskawaiter.getresult.aspx\"><$c$c>TaskAwaiter.GetResult()$c$c>)在这里所做的是,它需要外部 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.
code其中一个工作
有多个异常,其中一人后直接重新抛出的例子等待
是使用 Task.WhenAll()
而不是 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);
}
这篇关于如何更好地理解code /距离报表和QUOT;异步 - 处理多个异常&QUOT;文章?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!