Why can't I catch an exception from async code?

Everywhere I read it says the following code should work, but it doesn't.

public async Task DoSomething(int x)
{
   try
   {
      // Asynchronous implementation.
      await Task.Run(() => {
      throw new Exception();
      x++;
      });
   }
   catch (Exception ex)
   {
      // Handle exceptions ?
   }
}

That said, I'm not catching anything and get an "unhandled exception" originating at the 'throw' line. I'm clueless here.

Jon Skeet
people
quotationmark

Your code won't even compile cleanly at the moment, as the x++; statement is unreachable. Always pay attention to warnings.

However, after fixing that, it works fine:

using System;
using System.Threading.Tasks;

class Test
{
    static void Main(string[] args)
    {
        DoSomething(10).Wait();
    }

    public static async Task DoSomething(int x)
    {
        try
        {
            // Asynchronous implementation.
            await Task.Run(() => {
                throw new Exception("Bang!");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine("I caught an exception! {0}", ex.Message);
        }
    }
}

Output:

I caught an exception! Bang!

(Note that if you try the above code in a WinForms app, you'll have a deadlock because you'd be waiting on a task which needed to get back to the UI thread. We're okay in a console app as the task will resume on a threadpool thread.)

I suspect the problem is actually just a matter of debugging - the debugger may consider it unhandled, even though it is handled.

people

See more on this question at Stackoverflow