Obsługa wyjątków od synchronicznej części metody asynchronicznej

Mam do czynienia z sytuacją, w której zadanie, które rozpoczynam, może rzucać, a jednocześnie wykonywać synchronicznie na wątku początkowym. Coś takiego, w celach ilustracyjnych:

static async Task TestAsync()
{
    var random = new Random(Environment.TickCount).Next();
    if (random % 2 != 0)
        throw new ApplicationException("1st");

    await Task.Delay(2000);
    Console.WriteLine("after await Task.Delay");
    throw new ApplicationException("2nd");
}

Z kodu wywołującego chciałbym móc wyłapać wszelkie wyjątki, być może wyrzucone z części synchronicznej (tj. Doawait Task.Delay()). Oto jak to obecnie robię:

static void Main(string[] args)
{
    try
    {
        var task = TestAsync();
        if (task.IsFaulted)
            task.GetAwaiter().GetResult();
        Console.WriteLine("TestAsync continues asynchronously...");
    }
    catch (Exception e)
    {
        Console.WriteLine("Error: " + e.ToString());
    }

    Console.WriteLine("Press Enter to exit...");
    Console.ReadLine();
}

To działa, chociaż wygląda trochę kusząco, ponieważ nie maResult naTask.

Próbowałem teżtask.Wait() zamiasttask.GetAwaiter().GetResult(). To zawsze daje miAggregateException które muszę odwijać (raczej niż się spodziewamApplicationException bezpośrednio).

Czy są jakieś inne opcje?

[EDITED] Aby odnieść się do komentarzy: Robię to, ponieważ jeśli zadanie nie powiedzie się natychmiast, nie chcę dodawać go do listy oczekujących zadań, które utrzymuję. Samo zadanie nic nie wie o takiej liście (i nie musi). Nadal chcę rejestrować wyjątek i informować o tym użytkownika. Mogę też to zrobićthrow task.Exception, ale to nie dałoby ramce stosu wyjątków przechwyconej za pomocąExceptionDispatchInfo.

[AKTUALIZACJA] Zainspirowany innymi odpowiedziami i komentarzami: jeśli mam pełną kontrolęTestAsync i nie chcę przedstawiać nowych członków klasy, mogę również zrobić coś takiego jak poniżej. Przydaje się przy walidacji argumentów:

static Task TestAsync(int delay)
{
    if (delay < 0)
        throw new ArgumentOutOfRangeException("delay");

    Func<Task> asyncPart = async () =>
    {
        Console.WriteLine("await Task.Delay");
        await Task.Delay(delay);
        throw new ApplicationException("2nd");
    };

    return asyncPart();
}

questionAnswers(2)

yourAnswerToTheQuestion