-1

重新使用此答案中稍作修改的代码,如何修改它以实施@svick 的建议

但是如果你将任务保存到一个变量中并调用 task.Exception.Flatten(),这将返回两个异常

?

//C# console app
  class Program
  {
    static void Main(string[] args)
    {
      Test();
      Console.ReadLine();
    }
    async static Task Test()
    {
      Task containingTask, nullRefTask, argTask;
      try
      {
        containingTask = Task.Factory.StartNew
          (() =>
              {
                nullRefTask = Task.Factory.StartNew(() =>
                {
                    throw new NullReferenceException();
                }
                , TaskCreationOptions.AttachedToParent);

                argTask = Task.Factory.StartNew(() =>
                {
                    throw new ArgumentException();
                }
                , TaskCreationOptions.AttachedToParent);
              }
           );
        await containingTask;
        foreach(Exception ex in containingTask.Exception
                                              .Flatten().InnerExceptions)
        //Possible 'System.NullReferenceException'
        { //never entered
            Console.WriteLine("@@@@@"+ex.GetType().Name);
        } 
      }//try
      catch (AggregateException ex)
      {
        Console.WriteLine("** {0} **", ex.GetType().Name);
        foreach (var exc in ex.Flatten().InnerExceptions)
        {
          Console.WriteLine("$$$$$$"+exc.GetType().Name);
        }

//foreach (Exception exxx in containingTask.Exception.Flatten().InnerExceptions)
//Use of unassigned local variable 'containingTask' 
      }
//foreach (Exception exxx in containingTask.Exception.Flatten().InnerExceptions)
////Use of unassigned local variable 'containingTask'   
    }
  }

当我尝试containingTask.Exception.Flatten().InnerExceptions 使用或不使用 try-/catch-blocks 访问时,进出try-, catch-blocks 会产生错误:

Use of unassigned local variable 'containingTask'   

或者

Possible 'System.NullReferenceException'

如何从两个子任务中查看/获取两个异常?

更新:

这部分已从问题中删除,因为在更正错字后,代码会产生预期的结果

变体 #2(C# 控制台应用程序):
尝试从“异步 - 处理多个异常”中重现“解决方法”以查看所有子任务的所有异常:

class Program
{
    static void Main(string[] args)
    {
        Tst();
        Console.ReadLine();
    }
    async static Task Tst()
    {
        try
        {
            Task t= Task.Factory.StartNew
                (
                    () =>
                       {
                           Task.Factory.StartNew
                           (
                               () =>
                                  { throw new NullReferenceException(); }
                               ,TaskCreationOptions.AttachedToParent
                           );
                           Task.Factory.StartNew
                           (
                               () =>
                                   { throw new ArgumentException(); }
                                   , TaskCreationOptions.AttachedToParent
                           );
                       }
                );
            await t.ContinueWith
                    (
                        tsk =>
                          {
                              if (tsk.Exception != null)
                                   throw tsk.Exception;
                           }
                    );
        }
        catch (AggregateException ex)
        {
            foreach (var exc in ex.Flatten().InnerExceptions)
            {
                Console.WriteLine("** {0} **", exc.GetType().Name);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("## {0} ##", ex.GetType().Name);
        }
    }
}

4

1 回答 1

4

Task这与s 或async-无关await。如果您将代码简化为以下代码,您仍然会收到相同的错误:

string s;
try
{
    s = "something";
}
catch (SomeException)
{
}
Console.WriteLine(s);

编译器假定try在赋值执行之前可能会在内部抛出异常,因此您会收到此错误。为什么编译器会这样假设?因为它实际上可能发生:ThreadAbortException几乎可以在任何时候抛出。并且关于明确分配的规则不要试图太聪明以至于不知道可以抛出特定异常的规则是什么。

要解决此问题,null请将(或另一个默认值)分配给变量。

于 2013-05-17T18:46:42.777 回答