7

Code sample:

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Start");
        Foo f = new Foo();
        f.FooAsync();
    }

    public class Foo
    {
        public async void FooAsync()
        {
            try
            {
                await Task.Run(() =>
                {
                    Console.WriteLine("Throwing");
                    throw new Exception();
                });
            }
            catch (Exception)
            {
                Console.WriteLine("Caught");
            }
        }
    }
}

The above code when run from C# fiddle or from the console on my PC prints:

Start
Throwing
Caught

C# Fiddle Example

However, when I run it from Visual Studio (F5 in debug mode), I get the following message:

Exception Picture

I don't understand why I get "was not handled in user code" message from Visual Studio although running it from the console or C# fiddle is fine. Am I missing something obvious?

UPDATE

I've tried waiting on the task f.FooAsync().Wait(); in Main, but the exception is still reported as being unhandled (same error message).

i3arnon
  • 113,022
  • 33
  • 324
  • 344
Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • 1
    The code is fine, it is your debugger settings that are wrong. Click the "Open Exception Settings" link, untick the Thrown checkbox. If you turned it on intentionally then just click Continue. – Hans Passant Jun 06 '15 at 12:05
  • @HansPassant: Thanks. I found [more info about the problem here also](http://stackoverflow.com/a/16925282/906773). – Jesse Good Jun 06 '15 at 12:24

1 Answers1

9

First, what's special about this exception is that it's being thrown from Task.Run and for that scope, the exception really isn't handled by user-code.

The framework catches and stores the exception in the returned task for you to handle later, if you fail to do that it's an unobserved task exception (which in .Net 4.0 would've crashed the application).

The issue here is the "Enable Just My Code" feature in the settings. When the feature is turned on the debugger breaks on exceptions when you leave user-code and enter framework-code and at that point the exception really wasn't handled.

If you turn that feature off the debugger will not break on that exception as it will follow your code into the framework and see the exception being handled and stored in the task. The exception will then be re-thrown when you await the task and be handled by your code.


Since the handling that actually matters is the one being done by the framework, this is an even simpler example:

public static void Main()
{
    Task.Run(() =>
    {
        throw new Exception();
    });
    Console.ReadLine();
}

With "Enable Just My Code" turned on the debugger will break on the exception, without it the debugger will not.

i3arnon
  • 113,022
  • 33
  • 324
  • 344