web-dev-qa-db-fra.com

Le débogueur ne rompt pas / ne s'arrête pas pour les exceptions dans la méthode asynchrone

Lorsqu'un débogueur est attaché à un processus .NET, il s'arrête (généralement) lorsqu'une exception non gérée est levée.

Cependant, cela ne semble pas fonctionner lorsque vous êtes dans une méthode async.

Les scénarios que j'ai essayés auparavant sont répertoriés dans le code suivant:

class Program
{
    static void Main()
    {
        // Debugger stopps correctly
        Task.Run(() => SyncOp());

        // Debugger doesn't stop
        Task.Run(async () => SyncOp());

        // Debugger doesn't stop
        Task.Run((Func<Task>)AsyncTaskOp);

        // Debugger stops on "Wait()" with "AggregateException"
        Task.Run(() => AsyncTaskOp().Wait());

        // Throws "Exceptions was unhandled by user code" on "await"
        Task.Run(() => AsyncVoidOp());

        Thread.Sleep(2000);
    }

    static void SyncOp()
    {
        throw new Exception("Exception in sync method");
    }

    async static void AsyncVoidOp()
    {
        await AsyncTaskOp();
    }

    async static Task AsyncTaskOp()
    {
        await Task.Delay(300);
        throw new Exception("Exception in async method");
    }
}

Suis-je en train de manquer quelque chose? Comment puis-je faire en sorte que le débogueur interrompt/s'arrête sur l'exception dans AsyncTaskOp()?

55

Dans le menu Debug, sélectionnez Exceptions.... Dans la boîte de dialogue Exceptions, à côté de Common Language Runtime Exceptions ligne cochez la case Thrown.

35
Stephen Cleary

J'aimerais savoir si quelqu'un a découvert comment contourner ce problème? Peut-être un décor dans le dernier studio visuel ...?

Une solution désagréable mais réalisable (dans mon cas) était de lancer ma propre personnalisée exception, puis de modifier la réponse de Stephen Cleary:

Dans le menu Déboguer, sélectionnez Exceptions (Vous pouvez utiliser ce raccourci clavier Control + Alt + E) ... Dans la boîte de dialogue Exceptions, à côté de la ligne d'exceptions Common Language Runtime, cochez la case Thrown.

pour être plus précis, c.-à-d., ajoutez votre personnalisé exception dans la liste, puis cochez sa case "levée".

Par exemple:

async static Task AsyncTaskOp()
{
    await Task.Delay(300);
    throw new MyCustomException("Exception in async method");
}
3
Jimbob