Exceptions et performances

La levée d'exceptions peut nuire aux performances. Dans le cas de code qui échoue régulièrement, vous pouvez utiliser des modèles de design pour limiter les problèmes de performance. Cette rubrique décrit deux modèles de design utiles lorsque des exceptions sont susceptibles de dégrader considérablement les performances.

N'utilisez pas de codes d'erreur dans la mesure où les exceptions sont susceptibles de dégrader les performances.

Utilisez le design pour atténuer les problèmes de performance. Deux modèles sont décrits dans cette rubrique.

Envisagez d'utiliser le modèle « Tester-Doer » pour les membres qui sont susceptibles de lever des exceptions dans des scénarios classiques afin d'éviter des problèmes de performance liés aux exceptions.

Le modèle d'Appareil de contrôle-Faiseur divise un appel susceptible de lever des exceptions dans deux parties : un testeur et un exécuteur. Le testeur procède à un test de l'état susceptible de provoquer la levée d'une exception par l'exécuteur. Le test est inséré juste avant le code qui lève l'exception, permettant ainsi de s'en prévenir.

L'exemple de code suivant illustre la partie « exécuteur » de ce modèle. L'exemple contient une méthode qui lève une exception lorsqu'une valeur null Nothing en Visual Basic) lui est passée. Si cette méthode est souvent appelée, elle peut nuire aux performances.

Public Class Doer

    ' Method that can potential throw exceptions often.
    Public Shared Sub ProcessMessage(ByVal message As String)
        If (message = Nothing) Then
            Throw New ArgumentNullException("message")
        End If
    End Sub

    ' Other methods...
End Class
public class Doer
{
    // Method that can potential throw exceptions often.
    public static void ProcessMessage(string message)
    {
        if (message == null)
        {
            throw new ArgumentNullException("message");
        }
    }
    // Other methods...
}
public ref class Doer
{
public:
    // Method that can potential throw exceptions often.
    static void ProcessMessage(String^ message)
    {
        if (message == nullptr)
        {
            throw gcnew ArgumentNullException("message");
       }
    }
    // Other methods...
};

L'exemple de code suivant illustre la partie « testeur » de ce modèle. La méthode utilise un test pour empêcher l'appel à l'exécuteur (ProcessMessage) lorsque celui-ci est susceptible de lever une exception.

Public Class Tester

    Public Shared Sub TesterDoer(ByVal messages As ICollection(Of String))
        For Each message As String In messages
            ' Test to ensure that the call 
            ' won't cause the exception.
            If (Not (message) Is Nothing) Then
                Doer.ProcessMessage(message)
            End If
        Next
    End Sub
End Class
public class Tester
{
    public static void TesterDoer(ICollection<string> messages)
    {
        foreach (string message in messages)
        {
            // Test to ensure that the call
            // won't cause the exception.
            if (message != null)
            {
                Doer.ProcessMessage(message);
            }
        }
    }
}
public ref class Tester
{
public:
    static void TesterDoer(ICollection<String^>^ messages)
    {
        for each (String^ message in messages)
        {
            // Test to ensure that the call
            // won't cause the exception.
            if (message != nullptr)
            {
                Doer::ProcessMessage(message);
            }
        }
    }
};

Notez que vous risquez de devoir résoudre des conditions de concurrence critique si vous utilisez ce modèle dans une application multithread et que le test concerne un objet mutable. Un thread peut modifier l'état de l'objet mutable après le test mais avant l'exécution de l'exécuteur. Utilisez des techniques de synchronisation de threads pour résoudre ces problèmes.

Envisagez d'utiliser le modèle « TryParse » pour les membres susceptibles de lever des exceptions dans des scénarios classiques afin d'éviter les problèmes de performance liés aux exceptions.

Pour implémenter le modèle TryParse, vous fournissez deux méthodes différentes pour exécuter une opération susceptible de lever des exceptions dans des scénarios classiques. La première méthode, X, exécute l'opération et lève l'exception lorsque cela s'avère nécessaire. La deuxième méthode, TryX, ne lève pas d'exception mais retourne, au lieu de cela, une valeur Boolean signalant un succès ou un échec. Toutes les données retournées par un appel réussi à TryX sont retournées à l'aide d'un paramètre out (ByRef en Visual Basic). Les méthodes Parse et TryParse sont des exemples de ce modèle.

Fournissez un membre levant des exceptions pour chaque membre qui utilise le modèle TryParse.

En termes de conception, il est généralement incorrect de fournir uniquement la méthode TryX, car la compréhension des paramètres out est, dans ce cas, indispensable. En outre, pour la plupart des scénarios classiques, l'impact des exceptions sur les performances ne constitue pas un problème ; veillez plutôt à fournir des méthodes faciles à utiliser dans la plupart des scénarios classiques.

Portions Copyright 2005 Microsoft Corporation. Tous droits réservés.

Portions Copyright Addison-Wesley Corporation. Tous droits réservés.

Pour plus d'informations sur les règles de conception, consultez « règles de conception d'infrastructure : Conventions idiomes et modèles carnet de bibliothèques réutilisables framework » Krzysztof Cwalina et Brad Abrams, publiés par Addison-Wesley, 2005.

Voir aussi

Autres ressources

Instructions de conception pour le développement de bibliothèques de classes

Instructions de conception pour les exceptions