如何更好地理解code /距离报表和QUOT;异步 - 处理多个异常"文章? [英] How to better understand the code/statements from "Async - Handling multiple Exceptions" article?

查看:132
本文介绍了如何更好地理解code /距离报表和QUOT;异步 - 处理多个异常"文章?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

运行下面的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)

问题出在哪里:


  1. 的文章是错的?结果
    其中code /报表,以及如何才能正确地理解它改变?

  2. 我再现文章的第一code段犯了一个错误?

  3. 这是由于在.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 the NullReferenceException or the ArgumentException 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 awaited 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())在这里所做的是,它需要外部 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆