13

I thought that async methods were supposed to behave like normal methods until they arrived at an await.

Why does this not throw an exception?

Is there a way to have the exception thrown without awaiting?

using System;
using System.Threading.Tasks;

public class Test
{
    public static void Main()
    {
        var t = new Test();
        t.Helper();
    }

    public async Task Helper()
    {
        throw new Exception();
    }
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
Craig
  • 7,471
  • 4
  • 29
  • 46
  • 1
    As a historical note, exceptions were originally raised "directly" as you expect. However, this behavior was confusing because exceptions before and after the `await` would behave differently, and it could get *really* confusing if the `await` was conditional. – Stephen Cleary Jun 27 '14 at 01:15
  • @StephenCleary When was it changed? While in the CTP phase? – i3arnon Jun 27 '14 at 09:05
  • 1
    @I3arnon: Yes; IIRC only the first CTP behaved this way. – Stephen Cleary Jun 27 '14 at 12:05
  • 1
    @Craig, one other option is to use `async void`, check ["Fire and Forget approach"](http://stackoverflow.com/q/22864367/1768303). – noseratio Jun 27 '14 at 12:43

1 Answers1

17

An exception thrown inside an async method is, by design, stored inside the returned task. To get your hands on the exception you can:

  1. await the task: await t.Helper();
  2. Wait the task: t.Helper().Wait();
  3. Check the task's Exception property after the task has been completed: var task = t.Helper(); Log(task.Exception);
  4. Add a continuation to that task that handles the exception: t.Helper().ContinueWith(t => Log(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

Your best option is the first one. Simply await the task and handle the exception (unless there's a specific reason you can't do that). More in Task Exception Handling in .NET 4.5

i3arnon
  • 113,022
  • 33
  • 324
  • 344