Exporter (0) Imprimer
Développer tout
Cet article a fait l'objet d'une traduction manuelle. Déplacez votre pointeur sur les phrases de l'article pour voir la version originale de ce texte. Informations supplémentaires.
Traduction
Source

try-catch (référence C#)

L'instruction try-catch consiste en un bloc try suivi d'une ou de plusieurs clauses catch, qui désignent les gestionnaires des différentes exceptions.

Quand une exception est levée, le Common Language Runtime (CLR) recherche l'instruction catch qui gère cette exception. Si la méthode en cours d'exécution ne contient pas de bloc catch, le CLR examine la méthode qui a appelé la méthode actuelle, et ainsi de suite en remontant la pile des appels. Si aucun bloc catch n'est trouvé, le CLR affiche un message d'exception non gérée destiné à l'utilisateur et arrête l'exécution du programme.

Le bloc try contient le code protégé risquant de provoquer l'exception. Le bloc est exécuté jusqu'à la levée d'une exception ou jusqu'à sa réussite totale. Par exemple, la tentative suivante d'opérer un cast sur un objet null déclenche l'exception NullReferenceException :

object o2 = null;
try
{
    int i2 = (int)o2;   // Error
}

Bien que la clause catch puisse être employée sans arguments afin d'intercepter tout type d'exception, cette utilisation est déconseillée. En général, vous devez intercepter uniquement les exceptions que vous savez récupérer. Par conséquent, vous devez toujours spécifier un argument objet dérivé de System.Exception. Exemple :

catch (InvalidCastException e) 
{
}

Il est possible d'utiliser plus d'une clause catch spécifique dans la même instruction try-catch. Dans ce cas, l'ordre des clauses catch est important parce que les clauses catch sont examinées dans l'ordre. Interceptez les exceptions les plus spécifiques avant celles qui le sont le moins. Le compilateur génère une erreur si vous ordonnez vos blocs catch de sorte qu'un bloc ultérieur ne soit jamais atteint.

Une instruction throw peut être utilisée dans un bloc catch pour lever une nouvelle fois l'exception interceptée par l'instruction catch. L'exemple suivant extrait des informations source d'une exception IOException, puis lève l'exception à la méthode parente.

catch (FileNotFoundException e)
{
    // FileNotFoundExceptions are handled here.
}
catch (IOException e)
{
    // Extract some information from this exception, and then 
    // throw it to the parent method.
    if (e.Source != null)
        Console.WriteLine("IOException source: {0}", e.Source);
    throw;
}

Vous pouvez intercepter une exception et lever une exception différente. Dans ce cas, spécifiez l'exception que vous avez interceptée comme une exception interne, comme indiqué dans l'exemple suivant.

catch (InvalidCastException e) 
{
    // Perform some action here, and then throw a new exception.
    throw new YourCustomException("Put your error message here.", e);
}

Vous pouvez aussi lever à nouveau une exception lorsqu'une condition spécifiée a la valeur true, comme indiqué dans l'exemple suivant.


catch (InvalidCastException e)
{
    if (e.Data == null)
    {
        throw;
    }
    else
    {
        // Take some action.
    }
 }

Depuis un bloc try, initialisez uniquement les variables déclarées à l'intérieur. Sinon, une exception peut se produire avant la fin de l'exécution du bloc. Par exemple, dans l'exemple de code suivant, la variable n est initialisée dans le bloc try. Toute tentative d'utilisation de cette variable en dehors du bloc try dans l'instruction Write(n) générera une erreur de compilation.

static void Main() 
{
    int n;
    try 
    {
        // Do not initialize this variable here.
        n = 123;
    }
    catch
    {
    }
    // Error: Use of unassigned local variable 'n'.
    Console.Write(n);
}

Pour plus d'informations sur catch, consultez try-catch-finally.

Exceptions dans les méthodes Async

Une méthode async est marquée par un modificateur d' async et contient généralement un ou plusieurs attendent des expressions ou des instructions. Une expression d'attente implémente l'opérateur d' attendez à Task ou à Task<TResult>. Une expression await ne peut pas apparaître dans un bloc catch ou un bloc finally.

Lorsque le contrôle atteint await dans la méthode async, la progression de la méthode est interrompue jusqu'à ce que la tâche attendue se termine. Lorsque la tâche est terminée, l'opération peut continuer dans la méthode. Pour plus d'informations, consultez Programmation asynchrone avec Async et Await (C# et Visual Basic) et Flux de contrôle dans les programmes Async (C# et Visual Basic).

La tâche achevée à laquelle await est appliqué peut être dans un état censuré en raison d'une exception non gérée dans la méthode qui retourne la tâche. Attendre la tâche lève une exception. Une tâche peut également se terminer dans un état annulé si le processus asynchrone qui la retourne est annulé. Attendre une tâche annulée lève OperationCanceledException. Pour plus d'informations sur l'annulation d'un processus asynchrone, consultez Réglage de votre application Async (C# et Visual Basic).

Pour intercepter l'exception, attendre la tâche dans un bloc try, et intercepter l'exception dans le bloc catch associé. Pour obtenir un exemple, consultez la section « exemple ».

Une tâche peut être dans un état censuré car plusieurs exceptions se sont produites dans la méthode attendue async. Par exemple, la tâche peut être le résultat d'un appel à Task.WhenAll. Lorsque vous attendez une telle tâche, une seule des exceptions est interceptée, et vous ne pouvez pas prévoir quelle exception sera interceptée. Pour obtenir un exemple, consultez la section « exemple ».

Dans cet exemple, le bloc try contient un appel à la méthode ProcessString qui peut provoquer une exception. La clause catch contient le gestionnaire d'exceptions qui affiche simplement un message à l'écran. Quand l'instruction throw est appelée de l'intérieur de MyMethod, le système recherche l'instruction catch et affiche le message Exception caught.


    class TryFinallyTest
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        string s = null; // For demonstration purposes.

        try
        {            
            ProcessString(s);
        }

        catch (Exception e)
        {
            Console.WriteLine("{0} Exception caught.", e);
        }
    }
}
    /*
    Output:
    System.ArgumentNullException: Value cannot be null.
       at TryFinallyTest.Main() Exception caught.
     * */



Dans l'exemple suivant, deux blocs catch sont utilisés, et l'exception la plus spécifique, qui vient en premier, est interceptée.

Pour intercepter l'exception la moins spécifique, vous pouvez remplacer l'instruction throw dans ProcessString par l'instruction suivante : throw new Exception().

Si vous définissez le bloc catch de moindre détail d'abord dans l'exemple, le message d'erreur suivant s'affiche : A previous catch clause already catches all exceptions of this or a super type ('System.Exception').


class ThrowTest3
{
    static void ProcessString(string s)
    {
        if (s == null)
        {
            throw new ArgumentNullException();
        }
    }

    static void Main()
    {
        try
        {
            string s = null;
            ProcessString(s);
        }
        // Most specific:
        catch (ArgumentNullException e)
        {
            Console.WriteLine("{0} First exception caught.", e);
        }
        // Least specific:
        catch (Exception e)
        {
            Console.WriteLine("{0} Second exception caught.", e);
        }
    }
}
/*
 Output:
 System.ArgumentNullException: Value cannot be null.
 at Test.ThrowTest3.ProcessString(String s) ... First exception caught.
*/


L'exemple suivant illustre la gestion des exceptions pour les méthodes async. Pour intercepter une exception levée par une tâche async, affectez l'expression await dans un bloc try, et intercepter l'exception dans un bloc catch.

Supprimez les marques de commentaire de la ligne throw new Exception de l'exemple pour illustrer la gestion des exceptions. La propriété IsFaulted de la tâche a pour valeur True, la propriété Exception.InnerException de la tâche a pour valeur l'exception, l'exception est interceptée dans le bloc catch.

Supprimez les marques de commentaire de la ligne de throw new OperationCancelledException pour illustrer ce qui se produit lorsque vous annulez un processus asynchrone. La propriété IsCanceled de la tâche a pour valeur true, et l'exception est interceptée dans le bloc catch. Dans certaines conditions qui ne s'appliquent pas à cet exemple, la propriété IsFaulted de la tâche a pour valeur true et la propriété IsCanceled a pour valeur false.


        public async Task DoSomethingAsync()
        {
            Task<string> theTask = DelayAsync();

            try
            {
                string result = await theTask;
                Debug.WriteLine("Result: " + result);
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Exception Message: " + ex.Message);
            }
            Debug.WriteLine("Task IsCanceled: " + theTask.IsCanceled);
            Debug.WriteLine("Task IsFaulted:  " + theTask.IsFaulted);
            if (theTask.Exception != null)
            {
                Debug.WriteLine("Task Exception Message: "
                    + theTask.Exception.Message);
                Debug.WriteLine("Task Inner Exception Message: "
                    + theTask.Exception.InnerException.Message);
            }
        }

        private async Task<string> DelayAsync()
        {
            await Task.Delay(100);

            // Uncomment each of the following lines to
            // demonstrate exception handling.

            //throw new OperationCanceledException("canceled");
            //throw new Exception("Something happened.");
            return "Done";
        }

        // Output when no exception is thrown in the awaited method:
        //   Result: Done
        //   Task IsCanceled: False
        //   Task IsFaulted:  False

        // Output when an Exception is thrown in the awaited method:
        //   Exception Message: Something happened.
        //   Task IsCanceled: False
        //   Task IsFaulted:  True
        //   Task Exception Message: One or more errors occurred.
        //   Task Inner Exception Message: Something happened.

        // Output when a OperationCanceledException or TaskCanceledException
        // is thrown in the awaited method:
        //   Exception Message: canceled
        //   Task IsCanceled: True
        //   Task IsFaulted:  False



L'exemple suivant illustre la gestion des exceptions lorsque plusieurs tâches peuvent entraîner plusieurs exceptions. Le bloc try attend la tâche retournée par un appel à Task.WhenAll. La tâche est terminée lorsque les trois tâches auxquelles WhenAll est appliqué sont terminées.

Chacune des trois tâches cause une exception. Le bloc catch itère au sein des exceptions, qui se trouvent dans la propriété Exception.InnerExceptions de la tâche qui a été retournée par Task.WhenAll.


public async Task DoMultipleAsync()
{
    Task theTask1 = ExcAsync(info: "First Task");
    Task theTask2 = ExcAsync(info: "Second Task");
    Task theTask3 = ExcAsync(info: "Third Task");

    Task allTasks = Task.WhenAll(theTask1, theTask2, theTask3);

    try
    {
        await allTasks;
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Exception: " + ex.Message);
        Debug.WriteLine("Task IsFaulted: " + allTasks.IsFaulted);
        foreach (var inEx in allTasks.Exception.InnerExceptions)
        {
            Debug.WriteLine("Task Inner Exception: " + inEx.Message);
        }
    }
}

private async Task ExcAsync(string info)
{
    await Task.Delay(100);

    throw new Exception("Error-" + info);
}

// Output:
//   Exception: Error-First Task
//   Task IsFaulted: True
//   Task Inner Exception: Error-First Task
//   Task Inner Exception: Error-Second Task
//   Task Inner Exception: Error-Third Task


Pour plus d'informations, voir la Spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Ajouts de la communauté

AJOUTER
Microsoft réalise une enquête en ligne pour recueillir votre opinion sur le site Web de MSDN. Si vous choisissez d’y participer, cette enquête en ligne vous sera présentée lorsque vous quitterez le site Web de MSDN.

Si vous souhaitez y participer,
Afficher:
© 2015 Microsoft