Que se passe-t-il lorsqu'une méthode renvoie un Task contenu dans un bloc try/catch? Si ce Task non attendu lève une exception, est-ce que l'exception est interceptée / gérée?

Par exemple, si DoSomethingAsync() lève une exception, puis-je la gérer dans le bloc try/catch de TryCatchMethod()?

Task TryCatchMethod()
{
    try
    {
        return DoSomethingAsync();
    }
    catch(Exception e)
    {
        //Handle Exception
    }
}

async Task DoSomethingAsync()
{
   await Task.Delay(10000);
   throw new System.Exception();
}
1
Brandon Minnick 15 nov. 2017 à 22:54

3 réponses

L'exception est levée lorsque la tâche est attendue. Le compilateur a généré du code lorsqu'une tâche est attendue avec le mot-clé await déverrouille intelligemment les exceptions et les lance comme vous vous attendez avec une trace de pile raisonnablement raisonnable. Il est également levé si vous accédez au résultat de la tâche ou de l'attente d'appel, mais il est ensuite levé en tant qu'exception globale et ce n'est pas la meilleure pratique. Si vous n'attendez jamais la tâche, l'exception devient finalement une exception de tâche sans obstruction et peut être fatale pour votre programme et a également une trace de pile de déchets

1
Dave 15 nov. 2017 à 19:59

Une exception sera levée lorsque vous accédez au résultat de l'exécution de la tâche avec await task, task.Result ou task Wait().

Dans votre cas, si une exception est lancée à l'intérieur d'une tâche dans DoSomethingAsync(), elle ne sera pas interceptée par TryCatchMethod() mais sera interceptée par une méthode externe qui attend la tâche renvoyée par TryCatchMethod().

Vérifiez pour plus de détails: Exception Gestion (bibliothèque parallèle de tâches)

0
CodeFuller 15 nov. 2017 à 20:06

Si DoSomethingAsync lève une exception, l'exception est interceptée. S'il renvoie une tâche défectueuse, au lieu de la lancer, il n'y a aucune exception à attraper jusqu'à ce que vous essayiez d'obtenir le résultat de la tâche (en l'attendant). Puisque vous ne faites pas cela dans votre bloc try, il n'exécutera pas votre bloc catch.

Notez que si la méthode est marquée comme async, toutes les exceptions levées dans le corps de cette méthode sont interceptées et aboutissent à ce que la méthode retourne une tâche défaillante, plutôt que la méthode lève une exception. Pour que la méthode lève une exception, la méthode doit renvoyer un Task sans être marquée comme async.

6
Servy 15 nov. 2017 à 20:06
47316145