-1

Re-using slightly modified code from this answer, how to modify it in order to implement @svick's advice:

But if you save the Task into a variable and call task.Exception.Flatten(), that will return both exceptions

?

//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'   
    }
  }

When I am trying to access containingTask.Exception.Flatten().InnerExceptions with or without using try-/catch-blocks, in or out of try-, catch-blocks, produces errors:

Use of unassigned local variable 'containingTask'   

or

Possible 'System.NullReferenceException'

How to see/get both exceptions from both child tasks?

Update:

This part was removed from question since, after correcting a typo, the code produces expected results

Variant #2 (C# console app):
Trying to reproduce the "workaround" from "Async - Handling multiple Exceptions" to see all exceptions from all child tasks:

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);
        }
    }
}

Community
  • 1
  • 1
  • The first `AggregateException` (from the original task) becomes wrapped in a second `AggregateException` (from the continued task) and so you actually need to call `Flatten()` twice to get to the inner exceptions you want. – dlev May 17 '13 at 18:02
  • Sorry, I removed the Variant2. There was a stupid typo. After correcting it, Variant2 started to output expected results – Gennady Vanin Геннадий Ванин May 17 '13 at 18:12

1 Answers1

4

This has nothing to do with Tasks or async-await. If you simplify your code to the following one, you will still get the same error:

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

The compiler assumes that there might be an exception thrown inside the try but before the assignment is executed and so you get this error. Why does the compiler assume that? Because it can actually happen: ThreadAbortException can be thrown at pretty much any point. And the rules about definite assignment don't try to be too clever to know what are the rules where a specific exception can be thrown.

To fix this, assign null (or another default value) to the variable.

svick
  • 236,525
  • 50
  • 385
  • 514