2

I am trying to get more familiar with async/await programming and exception handling.

static void Main(string[] args)
{
   TestAsyncException();
}

private static async void TestAsyncException()
{
    try
    {
        var result = await Task.Factory.StartNew(() => DoSomething());
        //do something with the result
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
    }
}

private static int DoSomething()
{
    throw new Exception("Exception was thrown!");
}

I am expecting the Exception to be handled gracefully but instead the code execution stops and I get

An exception of type 'System.Exception' occurred in .. but was not handled in user code.

But then when I continue executing the code the Exception actually gets caught (and the message is displayed to the Console).

How am I supposed to catch the Exception without breaking the execution of my code?

rashfmnb
  • 9,959
  • 4
  • 33
  • 44
pgerchev
  • 177
  • 3
  • 13
  • 3
    If this is your real code, it's not a good example. `TestAsyncException` returns the control to `Main` while `await`ing, so `Main` returns too and the process is terminated. This interfers with the exceptions and it's hard to predict how they get handled. – René Vogt Apr 26 '16 at 12:56
  • I believe that the try catch needs to also be around the main thread running the async method as the exception gets thrown to the main thread (I might be wrong) – Alfie Goodacre Apr 26 '16 at 12:57
  • maybe this answer helps: http://stackoverflow.com/questions/5383310/catch-an-exception-thrown-by-an-async-method – Andrey Ischencko Apr 26 '16 at 13:03
  • @AlfieGoodacre The exception is caught before it gets to that point. – Servy Apr 26 '16 at 13:28

1 Answers1

4

First of all, your exception is handled. I believe you are seeing the code stop execution and display the error because you have Break When Thrown on for exceptions. Check your Exception Window (Debug -> Windows -> Exception Settings).

When you use a return type of void on an async method, you lack the ability to get any sort of information back from the method - it's fire and forget. Except in specific situations, this is bad practice. Always have your async methods return a Task or Task<T>:

private static async Task TestAsyncException()

Now, your main method can listen to the task:

static void Main(string[] args)
{
    TestAsyncException().Wait(); // or whatever you want to do with the task
    Console.Read();
}

Normally, you could use await to unwrap the task here, but that's not allowed in the application entry point.

Jonesopolis
  • 25,034
  • 12
  • 68
  • 112