如何更好地理解“异步 – 处理多个exception”一文中的代码/语句?
运行以下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”博客文章中再现第一个片段,该文章讲述了:
以下代码将捕获单个NullReferenceException或ArgumentExceptionexception(将忽略AggregateException)
问题出在哪儿:
- 这篇文章错了吗?
哪些代码/语句以及如何更改以便正确理解它? - 我在复制文章的第一个代码片段时犯了错误?
- 这是由于.NET 4.0 / VS2010 Async CTP扩展中的一个错误,我正在使用?
Update1 (响应svick的回答 )
添加代码后
//****** Update1 - Start of Added code foreach (var exc in ex.Flatten().InnerExceptions) { Console.WriteLine(exc.GetType().Name); } //****** Update1 - End of Added code
产生的输出是:
** AggregateException ** NullReferenceException
所以,同样评论马特史密斯 :
捕获的
AggregateException
仅包含抛出的一个exception(NullReferenceException
或ArgumentException
具体取决于子Tasks的执行顺序)
最有可能的是,这篇文章仍然是正确的,或者至少非常有用。 我只需要了解如何更好地阅读/理解/使用它
Update2(响应svick的回答 )
执行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
?
这篇文章错了。 运行代码时, await
ed Task
包含一个如下所示的exception:
AggregateException AggregateException NullReferenceException AggregateException ArgumentException
await
(或者更确切地说, TaskAwaiter.GetResult()
)在这里做的是它接受外部AggregateException
并重新抛出其第一个子exception。 在这里,这是另一个AggregateException
,所以抛出的是什么。
代码示例,其中一个Task
有多个exception,其中一个在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); }
为了回应你的“更新2”,推理仍然与svick的答案相同。 该任务包含AggregateException
,但等待它会抛出第一个InnerException
。
您需要的其他信息在Task.WhenAll文档中(强调我的):
如果任何提供的任务在故障状态下完成,则返回的任务也将在故障状态下完成,其中exception将包含来自每个提供的任务的一组未包装的exception的聚合。
因此Task的exception将如下所示:
上述就是C#学习教程:如何更好地理解“异步 – 处理多个exception”一文中的代码/语句?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
AggregateException NullReferenceException ArgumentException
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1043394.html