gpt4 book ai didi

c# - 如何更好地理解 "Async - Handling multiple Exceptions"文章中的代码/语句?

转载 作者:行者123 更新时间:2023-11-30 13:58:31 24 4
gpt4 key购买 nike

运行以下 C# 控制台应用程序

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 **

尽管如此,上面的代码正在重现 "Async - Handling multiple Exceptions" 中的第一个片段博客文章,讲述了它:

the following code will catch a single NullReferenceException or ArgumentException exception (the AggregateException will be ignored)

问题出在哪里:

  1. 文章有误?
    哪些代码/语句以及如何更改才能正确理解它?
  2. 我在复制文章的第一个代码片段时出错了?
  3. 这是由于 .NET 4.0/VS2010 异步 CTP 扩展中的错误,我正在使用?

Update1(响应svick's answer)

添加代码后

//******  Update1 - Start of Added code
foreach (var exc in ex.Flatten().InnerExceptions)
{
Console.WriteLine(exc.GetType().Name);
}
//****** Update1 - End of Added code

产生的输出是:

** AggregateException **
NullReferenceException

所以,还有commented Matt Smith :

the AggregateException that is caught, contains only one of the exceptions that was thrown (either the NullReferenceException or the ArgumentException depending on the order of execution of the child Tasks)

很有可能,这篇文章仍然正确,或者至少非常有用。我只需要了解如何更好地阅读/理解/使用它

Update2(响应svick's answer)

执行svick的代码:

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

最佳答案

这篇文章是错误的。当您运行代码时,awaited Task 包含如下所示的异常:

AggregateException
AggregateException
NullReferenceException
AggregateException
ArgumentException

await(或者更具体地说,TaskAwaiter.GetResult())在这里所做的是它接受外部 AggregateException 并重新抛出它的第一个子异常。在这里,这是另一个 AggregateException,所以这就是抛出的内容。

Task 有多个异常并且其中一个在 await 之后直接重新抛出的代码示例将使用 Task.WhenAll() 而不是 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);
}

关于c# - 如何更好地理解 "Async - Handling multiple Exceptions"文章中的代码/语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16571791/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com