Behandlung von Ausnahmen vom synchronen Teil der asynchronen Methode

Ich habe es mit der Situation zu tun, in der die von mir gestartete Aufgabe möglicherweise ausgeführt wird, während sie gleichzeitig im ersten Thread ausgeführt wird. So etwas zur Veranschaulichung:

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");
}

Vom aufrufenden Code möchte ich in der Lage sein, Ausnahmen abzufangen, die möglicherweise vom synchronen Teil (d. H. Bis zumawait Task.Delay()). So mache ich es gerade:

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();
}

Dies funktioniert, obwohl es ein bisschen mundvoll aussieht, da es keine gibtResult auf derTask.

Ich habe es auch versuchttask.Wait() Anstatt vontask.GetAwaiter().GetResult(). Das gibt mir immerAggregateException was ich auspacken muss (eher als erwartet)ApplicationException direkt).

Gibt es noch andere Möglichkeiten?

[EDITED] So gehen Sie auf die Kommentare ein: Ich tue dies, weil ich die Aufgabe, wenn sie sofort fehlschlägt, nicht zur Liste der ausstehenden Aufgaben, die ich verwalte, hinzufügen möchte. Die Aufgabe selbst weiß nichts über eine solche Liste (und muss es auch nicht). Ich möchte die Ausnahme weiterhin protokollieren und den Benutzer darauf aufmerksam machen. Ich könnte es auch tunthrow task.Exception, aber das würde nicht den Ausnahmestapelrahmen geben, der mit gefangen wirdExceptionDispatchInfo.

[AKTUALISIEREN] Inspiriert von anderen Antworten und Kommentaren: Wenn ich die volle Kontrolle habeTestAsync und ich möchte keine neuen Klassenmitglieder vorstellen, ich könnte auch so etwas tun. Es kann nützlich sein, wenn Sie Argumente validieren:

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();
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage