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

L'instruction try-catch consiste en un bloc try suivi d'une ou plusieurs clauses catch qui spécifient des gestionnaires pour différentes exceptions.The try-catch statement consists of a try block followed by one or more catch clauses, which specify handlers for different exceptions.

Quand une exception est levée, le Common Language Runtime (CLR) recherche l'instruction catch qui gère cette exception.When an exception is thrown, the common language runtime (CLR) looks for the catch statement that handles this exception. Si la méthode en cours d'exécution ne contient pas un tel bloc catch, le CLR examine la méthode qui a appelé la méthode actuelle, puis remonte la pile des appels.If the currently executing method does not contain such a catch block, the CLR looks at the method that called the current method, and so on up the call stack. Si aucun bloc catch n'est trouvé, alors le CLR affiche un message d'exception non gérée à l'utilisateur et arrête l'exécution du programme.If no catch block is found, then the CLR displays an unhandled exception message to the user and stops execution of the program.

Le bloc try contient le code protégé susceptible de provoquer l'exception.The try block contains the guarded code that may cause the exception. Le bloc est exécuté jusqu'à ce qu'une exception soit levée ou qu'il se soit correctement terminé.The block is executed until an exception is thrown or it is completed successfully. Par exemple, la tentative suivante d'effectuer un cast d'un objet null déclenche l'exception NullReferenceException :For example, the following attempt to cast a null object raises the NullReferenceException exception:

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

Bien que la clause catch puisse être utilisée sans arguments pour intercepter tout type d'exception, cette utilisation est déconseillée.Although the catch clause can be used without arguments to catch any type of exception, this usage is not recommended. En général, vous devez intercepter uniquement les exceptions desquelles vous savez comment récupérer.In general, you should only catch those exceptions that you know how to recover from. Par conséquent, vous devez toujours spécifier un argument d'objet dérivé de System.Exception, par exemple :Therefore, you should always specify an object argument derived from System.Exception For example:

catch (InvalidCastException e)
{
}

Il est possible d'utiliser plusieurs clauses catch spécifiques dans la même instruction try-catch.It is possible to use more than one specific catch clause in the same try-catch statement. Dans ce cas, l'ordre des clauses catch est important car les clauses catch sont examinées dans l'ordre.In this case, the order of the catch clauses is important because the catch clauses are examined in order. Interceptez les exceptions plus spécifiques avant les moins spécifiques.Catch the more specific exceptions before the less specific ones. Le compilateur produit une erreur si vous organisez vos blocs catch de sorte qu'un bloc ultérieur ne puisse jamais être atteint.The compiler produces an error if you order your catch blocks so that a later block can never be reached.

L'utilisation d'arguments catch constitue un moyen de filtrer les exceptions à gérer.Using catch arguments is one way to filter for the exceptions you want to handle. Vous pouvez également utiliser un filtre d’exception qui examine l’exception pour déterminer si elle doit être prise en charge.You can also use an exception filter that further examines the exception to decide whether to handle it. Si le filtre d’exception retourne la valeur false, la recherche d’un gestionnaire se poursuit.If the exception filter returns false, then the search for a handler continues.

catch (ArgumentException e) when (e.ParamName == "…")
{
}

L'utilisation de filtres d'exceptions est préférable à une interception et une nouvelle levée (voir explication ci-dessous), car les filtres laissent la pile intact.Exception filters are preferable to catching and rethrowing (explained below) because filters leave the stack unharmed. Si un gestionnaire ultérieur vide la pile, vous pouvez déterminer d'où l'exception provient à l'origine, au lieu de déterminer simplement le dernier emplacement auquel elle a été levée.If a later handler dumps the stack, you can see where the exception originally came from, rather than just the last place it was rethrown. Une utilisation courante des expressions de filtre d'exception est liée à la journalisation.A common use of exception filter expressions is logging. Vous pouvez créer un filtre qui retourne toujours false et dont la sortie est journalisée. Vous pouvez journaliser les exceptions au fur et à mesure sans avoir à les prendre en charge et à les lever de nouveau.You can create a filter that always returns false that also outputs to a log, you can log exceptions as they go by without having to handle them and rethrow.

Une instruction throw peut être utilisée dans un bloc catch pour lever une nouvelle fois l’exception interceptée par l’instruction catch.A throw statement can be used in a catch block to re-throw the exception that is caught by the catch statement. L'exemple suivant extrait des informations sources d'une exception IOException, puis lève l'exception à la méthode parente.The following example extracts source information from an IOException exception, and then throws the exception to the parent method.

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 seule exception et lever une exception différente.You can catch one exception and throw a different exception. Dans ce cas, spécifiez l'exception que vous interceptez en tant qu'exception interne, comme illustré dans l'exemple suivant.When you do this, specify the exception that you caught as the inner exception, as shown in the following example.

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

Vous pouvez également lever à nouveau une exception quand une condition spécifiée a la valeur true, comme illustré dans l'exemple suivant.You can also re-throw an exception when a specified condition is true, as shown in the following example.

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

Notes

Il est également possible d’utiliser un filtre d’exception pour obtenir un résultat similaire d’une manière souvent plus claire (sans modifier la pile, comme expliqué précédemment dans ce document).It is also possible to use an exception filter to get a similar result in an often cleaner fashion (as well as not modifying the stack, as explained earlier in this document). L’exemple suivant a un comportement similaire à l’exemple précédent pour les appelants.The following example has a similar behavior for callers as the previous example. La fonction lève et retourne InvalidCastException à l’appelant quand e.Data a une valeur null.The function throws the InvalidCastException back to the caller when e.Data is null.

catch (InvalidCastException e) when (e.Data != null)
{
    // Take some action.
}

Dans un bloc try, initialisez uniquement les variables qui y sont déclarées.From inside a try block, initialize only variables that are declared therein. Sinon, une exception peut se produire avant la fin de l'exécution du bloc.Otherwise, an exception can occur before the execution of the block is completed. Par exemple, dans l'exemple de code suivant, la variable n est initialisée à l'intérieur du bloc try.For example, in the following code example, the variable n is initialized inside the try block. Une tentative d'utilisation de cette variable en dehors du bloc try dans l'instruction Write(n) génère une erreur du compilateur.An attempt to use this variable outside the try block in the Write(n) statement will generate a compiler error.

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 l’interception, consultez try-catch-finally.For more information about catch, see try-catch-finally.

Exceptions dans les méthodes asyncExceptions in async methods

Une méthode async est marquée par un modificateur async et contient généralement une ou plusieurs expressions ou instructions await.An async method is marked by an async modifier and usually contains one or more await expressions or statements. Une expression await applique l’opérateur await à un Task ou Task<TResult>.An await expression applies the await operator to a Task or Task<TResult>.

Quand le contrôle atteint un await dans la méthode async, la progression de la méthode est interrompue jusqu'à ce que la tâche attendue se termine.When control reaches an await in the async method, progress in the method is suspended until the awaited task completes. Quand la tâche est terminée, l’exécution peut reprendre dans la méthode.When the task is complete, execution can resume in the method. Pour plus d’informations, consultez Programmation asynchrone avec Async et Await et Flux de contrôle dans les programmes Async.For more information, see Asynchronous Programming with async and await and Control Flow in Async Programs.

La tâche terminée à laquelle await est appliqué peut être dans un état d'erreur en raison d'une exception non gérée dans la méthode qui retourne la tâche.The completed task to which await is applied might be in a faulted state because of an unhandled exception in the method that returns the task. L'attente de la tâche lève une exception.Awaiting the task throws an exception. Une tâche peut également se terminer dans un état annulé si le processus asynchrone qui la retourne est annulé.A task can also end up in a canceled state if the asynchronous process that returns it is canceled. L'attente d'une tâche annulée lève une OperationCanceledException.Awaiting a canceled task throws an OperationCanceledException. Pour plus d’informations sur la façon d’annuler un processus asynchrone, consultez Réglage de votre application Async.For more information about how to cancel an asynchronous process, see Fine-Tuning Your Async Application.

Pour intercepter l'exception, attendez la tâche dans un bloc try, puis interceptez l'exception dans le bloc catch associé.To catch the exception, await the task in a try block, and catch the exception in the associated catch block. Pour obtenir un exemple, consultez la section Exemple de la méthode async.For an example, see the Async method example section.

Une tâche peut être dans un état d'erreur car plusieurs exceptions se sont produites dans la méthode async attendue.A task can be in a faulted state because multiple exceptions occurred in the awaited async method. Par exemple, la tâche peut être le résultat d'un appel à Task.WhenAll.For example, the task might be the result of a call to Task.WhenAll. Quand vous attendez une telle tâche, une seule des exceptions est interceptée et vous ne pouvez pas prévoir laquelle.When you await such a task, only one of the exceptions is caught, and you can't predict which exception will be caught. Pour obtenir un exemple, consultez la section Exemple Task.WhenAll.For an example, see the Task.WhenAll example section.

ExempleExample

Dans l'exemple suivant, le bloc try contient un appel à la méthode ProcessString qui risque de provoquer une exception.In the following example, the try block contains a call to the ProcessString method that may cause an exception. La clause catch clause contient le gestionnaire d'exceptions qui affiche simplement un message à l'écran.The catch clause contains the exception handler that just displays a message on the screen. Quand l'instruction throw est appelée depuis ProcessString, le système recherche l'instruction catch et affiche le message Exception caught.When the throw statement is called from inside ProcessString, the system looks for the catch statement and displays the 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.
 * */

Exemple de deux blocs catchTwo catch blocks example

Dans l'exemple suivant, deux blocs catch sont utilisés, et l'exception la plus spécifique, qui apparaît la première, est interceptée.In the following example, two catch blocks are used, and the most specific exception, which comes first, is caught.

Pour intercepter l'exception la moins spécifique, vous pouvez remplacer l'instruction throw dans ProcessString par l'instruction suivante : throw new Exception().To catch the least specific exception, you can replace the throw statement in ProcessString with the following statement: throw new Exception().

Si vous placez le bloc catch le moins spécifique en premier 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').If you place the least-specific catch block first in the example, the following error message appears: 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.
*/

Exemple de la méthode asyncAsync method example

L'exemple suivant illustre la gestion des exceptions pour les méthodes async.The following example illustrates exception handling for async methods. Pour intercepter une exception levée par une tâche async, placez l'expression await dans un bloc try et interceptez-la dans un bloc catch.To catch an exception that an async task throws, place the await expression in a try block, and catch the exception in a catch block.

Supprimez les marques de commentaire de la ligne throw new Exception dans l'exemple pour illustrer la gestion des exceptions.Uncomment the throw new Exception line in the example to demonstrate exception handling. La propriété IsFaulted de la tâche a la valeur True, la propriété Exception.InnerException de la tâche a la valeur de l'exception et l'exception est interceptée dans le bloc catch.The task's IsFaulted property is set to True, the task's Exception.InnerException property is set to the exception, and the exception is caught in the catch block.

Supprimez les marques de commentaire de la ligne throw new OperationCanceledException pour montrer ce qui se passe quand vous annulez un processus asynchrone.Uncomment the throw new OperationCanceledException line to demonstrate what happens when you cancel an asynchronous process. La propriété IsCanceled de la tâche a la valeur true et l'exception est interceptée dans le bloc catch.The task's IsCanceled property is set to true, and the exception is caught in the catch block. Sous certaines conditions qui s'appliquent à cet exemple, la propriété IsFaulted de la tâche a la valeur true et IsCanceled a la valeur false.Under some conditions that don't apply to this example, the task's IsFaulted property is set to true and IsCanceled is set to 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

Exemple Task.WhenAllTask.WhenAll example

L’exemple suivant illustre la gestion des exceptions quand plusieurs tâches peuvent entraîner plusieurs exceptions.The following example illustrates exception handling where multiple tasks can result in multiple exceptions. Le bloc try attend la tâche retournée par un appel à Task.WhenAll.The try block awaits the task that's returned by a call to Task.WhenAll. La tâche est terminée quand les trois tâches auxquelles WhenAll est appliqué sont terminées.The task is complete when the three tasks to which WhenAll is applied are complete.

Chacune de ces trois tâches provoque une exception.Each of the three tasks causes an exception. Le bloc catch itère au sein des exceptions, qui sont trouvent dans la propriété Exception.InnerExceptions de la tâche retournée par Task.WhenAll.The catch block iterates through the exceptions, which are found in the Exception.InnerExceptions property of the task that was returned by 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

spécification du langage C#C# language specification

Pour plus d’informations, consultez la section Instruction try de la spécification du langage C#.For more information, see The try statement section of the C# language specification.

Voir aussiSee also