Gestion et levée des exceptions

Les applications doivent pouvoir gérer de manière cohérente les erreurs qui se produisent au moment de l'exécution. Le Common Language Runtime fournit un modèle pour la notification des erreurs aux applications de façon uniforme. Toutes les opérations .NET Framework indiquent une erreur en levant des exceptions.

Cette rubrique contient les sections suivantes :

  • Exceptions dans le .NET Framework

  • Exceptions et méthodes traditionnelles de gestion des erreurs

  • Gestion des exceptions par le runtime

  • Filtrage des exceptions runtime

  • Rubriques connexes

  • Référence

Exceptions dans le .NET Framework

Une exception est une condition d'erreur ou un comportement inattendu rencontré par un programme en cours d'exécution. Les exceptions peuvent être déclenchées à cause d'une erreur dans votre code ou dans le code que vous appelez (tel qu'une bibliothèque partagée), de ressources de système d'exploitation non disponibles, de conditions inattendues rencontrées par le Common Language Runtime (telles que du code qui ne peut pas être vérifié), etc. Votre application peut récupérer suite à certaines de ces conditions, mais pas avec d'autres. Bien que vous puissiez récupérer suite à la plupart des exceptions d'application, vous ne pouvez pas récupérer suite à la plupart des exceptions runtime.

Dans le .NET Framework, une exception est un objet qui hérite de la classe System.Exception. Une exception est levée à partir d'une partie du code où un problème s'est produit. L'exception remonte la pile qu'à sa prise en charge par l'application ou l'arrêt du programme.

Retour au début

Exceptions etméthodes traditionnelles de gestion des erreurs

Traditionnellement, le modèle de gestion des erreurs d'un langage reposait soit sur le mode unique utilisé par le langage en question pour détecter des erreurs et leur trouver des gestionnaires appropriés, soit sur le mécanisme de gestion des erreurs fourni par le système d'exploitation. Le runtime implémente la gestion des exceptions de la façon suivante :

  • gère les exceptions sans tenir compte du langage qui génère l'exception ni du langage qui gère l'exception ;

  • ne requiert aucune syntaxe particulière pour la gestion des exceptions, mais laisse chaque langage définir sa propre syntaxe ;

  • accepte la levée d'exceptions interprocessus et même au-delà des limites d'ordinateur.

Les exceptions offrent plusieurs avantages par rapport à d'autres méthodes de notification d'erreurs, telles que les codes de retour. Les erreurs ne passent pas inaperçues. La propagation des valeurs non valides à travers le système est interrompue. Vous n'êtes pas obligé de vérifier les codes de retour. Un code de gestion des exceptions peut être aisément ajouté pour augmenter la fiabilité du programme. Enfin, la gestion des exceptions par le runtime est plus rapide que la gestion des erreurs C++ qui fait appel à Windows.

Dans la mesure où les threads d'exécution parcourent couramment des blocs de code managé et non managé, le runtime peut lever ou intercepter des exceptions dans un code managé ou non managé. Le code non managé peut comprendre à la fois des exceptions SEH de style C++ et des HRESULTS COM.

Gestion des exceptions par le runtime

Le runtime utilise un modèle de gestion des exceptions fondé sur des objets exception et des blocs de code protégés. Un objet Exception est créé pour représenter une exception lorsque celle-ci est levée.

Le runtime crée une table d'informations sur les exceptions pour chaque exécutable. Chaque méthode de l'exécutable a un tableau associé d'informations de gestion des exceptions (qui peut être vide) contenu dans la table d'informations sur les exceptions. Chaque entrée du tableau décrit un bloc de code protégé, d'éventuels filtres d'exceptions associés à ce code et d'éventuels gestionnaires d'exceptions (instructions catch). Cette table d'exceptions est extrêmement efficace et aucune dégradation des performances n'est constatée, que ce soit au niveau du temps du processeur ou de l'utilisation de la mémoire, lorsqu'une exception ne se produit pas. Les ressources sont utilisées uniquement lorsqu'une exception se produit.

La table d'informations sur les exceptions représente quatre types de gestionnaires d'exceptions pour les blocs protégés :

  • Un gestionnaire finally qui s'exécute à chaque sortie du bloc, que cette situation soit le résultat d'un flux de contrôle normal ou d'une exception non gérée.

  • Un gestionnaire de pannes qui doit s'exécuter lorsqu'une exception se produit, mais ne s'exécute pas à l'issue de l'achèvement du flux de contrôle normal.

  • Un gestionnaire filtré par type qui gère toute exception d'une classe spécifiée ou l'une de ses classes dérivées.

  • Un gestionnaire filtré par l'utilisateur qui exécute un code spécifié par l'utilisateur afin de déterminer si l'exception doit être gérée par le gestionnaire associé ou passée au bloc protégé suivant.

Chaque langage implémente ces gestionnaires d'exceptions selon ses propres spécifications. Par exemple, Visual Basic donne accès à un gestionnaire filtré par l'utilisateur via une comparaison de variables (en utilisant le mot clé When ) dans l'instruction catch ; C# n'implémente pas le gestionnaire filtré par l'utilisateur.

Lorsqu'une exception se produit, le runtime déclenche un processus en deux étapes :

  1. Le runtime recherche dans le tableau le premier bloc protégé qui :

    • protège une partie contenant l'instruction en cours d'exécution, et

    • contient un gestionnaire d'exceptions ou un filtre chargé de la gestion de l'exception.

  2. En cas de concordance, le runtime crée un objet Exception qui décrit l'exception. Le runtime exécute ensuite toutes les instructions finally ou fault situées entre l'instruction où l'exception s'est produite et l'instruction qui gère l'exception. Notez que l'ordre des gestionnaires d'exceptions est important : le gestionnaire d'exceptions le plus profond est évalué en premier. Notez également que les gestionnaires d'exceptions peuvent accéder aux variables locales et à la mémoire locale de la routine qui intercepte l'exception, mais les éventuelles valeurs intermédiaires survenant au moment où l'exception est levée sont perdues.

    Si aucune correspondance n'est trouvée dans la méthode en cours, le runtime explore chaque appelant de la méthode en cours, puis poursuit ce chemin en remontant la pile. Si aucun appelant n'a de correspondance, le runtime autorise le débogueur à accéder à l'exception. Si le débogueur ne s'attache pas à l'exception, le runtime déclenche l'événement AppDomain.UnhandledException. Si aucun écouteur n'existe pour cet événement, le runtime fait un dump d'une trace de la pile et arrête l'application.

Retour au début

Filtrage des exceptions runtime

Vous pouvez filtrer les exceptions que vous interceptez et gérez soit par type soit par des critères définis par l'utilisateur.

Les gestionnaires filtrés par type gèrent un type particulier d'exception (ou de classes qui en sont dérivées). L'exemple suivant illustre un gestionnaire filtré par type conçu pour intercepter une exception spécifique, en l'occurrence FileNotFoundException.

Catch e As FileNotFoundException
    Console.WriteLine("[Data File Missing] {0}", e)
catch (FileNotFoundException e)
{
    Console.WriteLine("[Data File Missing] {0}", e);
}
catch (FileNotFoundException^ e)
{
    Console::WriteLine("[Data File Missing] {0}", e);
}

Les gestionnaires d'exceptions filtrés par l'utilisateur interceptent et gèrent les exceptions selon des critères que vous définissez pour l'exception. Pour plus d'informations sur ce type de filtrage des exceptions, consultez Utilisation d'exceptions spécifiques dans un bloc catch.

Retour au début

Rubriques connexes

Titre

Description

Classe et propriétés d'exception

Décrit les éléments d'un objet exception.

Hiérarchie des exceptions

Décrit les exceptions à partir desquelles dérivent la plupart des exceptions.

Notions de base de la gestion des exceptions

Explique comment gérer les exceptions à l'aide des instructions catch, throw et finally.

Meilleures pratiques pour la gestion des exceptions

Décrit les méthodes suggérées pour la gestion des exceptions.

Gestion des exceptions COM Interop

Indique comment gérer les exceptions levées et interceptées dans un code non managé.

Comment : mapper des HRESULT et des exceptions

Décrit le mappage des exceptions entre le code managé et le code non managé.

Retour au début

Référence

System.Exception

System.ApplicationException

System.SystemException