Quite often people think that when using async-await several threads are involved, while in fact it is not, unless you specify to do so.
Read Eric Lippert about async-await search somewhere in the middle for async await.
He compares async await with a cook: when toasting bread he can wait until the bread is toasted before boiling water for tea and eggs. It would be more efficient if he started boiling water and then turn back to see if the bread is toasted.
The same happens in your code. During your await task.Delay your thread doesn't start waiting. Instead it goes up its call stack to see if one of the callers (who all must be async!) is not awaiting, and thus can continue processing without the result of its calls. After a while it returns to see if the Task.Delay is finished and continues the next statement where the exception is thrown.
Note that in this scenario there is only one thread involved. Exception catching is done as all other exception catching. Although the catcher can check the call stack, he is not sure what pieces of code are executed and which ones aren't. In this respect there is no big difference with non-async-await