Goal:
I am confused by the behavior I am seeing with exceptions in my .Net Core library. The goal of this question is to understand why it is doing what I am seeing.
Executive Summary
I thought that when an async method is called, the code in it is executed synchronously until it hits the first await. If that is the case, then, if an exception is thrown during that "synchronous code", why is it not propagated up to the calling method? (As a normal synchronous method would do.)
Example Code:
Given the following code in a .Net Core Console Application:
static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    try
    {
        NonAwaitedMethod();
    }
    catch (Exception e)
    {
        Console.WriteLine("Exception Caught");
    }
    Console.ReadKey();
}
public static async Task NonAwaitedMethod()
{
    Task startupDone = new Task(() => { });
    var runTask = DoStuff(() =>
    {
        startupDone.Start();
    });
    var didStartup = startupDone.Wait(1000);
    if (!didStartup)
    {
        throw new ApplicationException("Fail One");
    }
    await runTask;
}
public static async Task DoStuff(Action action)
{
    // Simulate starting up blocking
    var blocking = 100000;
    await Task.Delay(500 + blocking);
    action();
    // Do the rest of the stuff...
    await Task.Delay(3000);
}
}
Scenarios:
- When run as is, this code will throw an exception, but, unless you have a break point on it, you will not know it. The Visual Studio Debugger nor the Console will give any indication that there was an issue (aside from a one line note in the Output screen). 
- Swap the return type of - NonAwaitedMethodfrom- Taskto- void. This will cause the Visual Studio Debugger to now break on the exception. It will also be printed out in the console. But notably, the exception is NOT caught in the- catchstatement found in- Main.
- Leave the return type of - NonAwaitedMethodas- void, but take off the- async. Also change the last line from- await runTask;to- runTask.Wait();(This essentially removes any async stuff.) When run, the exception is caught in the- catchstatement in the- Mainmethod.
So, to summarize:
| Scenario   | Caught By Debugger | Caught by Catch |  
|------------|--------------------|-----------------|  
| async Task | No                 | No              |  
| async void | Yes                | No              |  
| void       | N/A                | Yes             |  
Questions:
I thought that because the exception was thrown before an await was done, that it would execute synchronously up to, and through the throwing of the exception.
Hence my question of: Why does neither scenario 1 or 2 get caught by the catch statement?
Also, why does swapping from Task to void return type cause the exception to get caught by the Debugger?  (Even though I am not using that return type.)
 
     
     
    