Ausnahmen und Leistung

Das Auslösen von Ausnahmen kann die Leistung beeinträchtigen. Für Code, der routinemäßig fehlschlägt, können Sie Entwurfsmuster verwenden, um Leistungseinbußen zu minimieren. In diesem Thema werden zwei Entwurfsmuster beschrieben, die sich anbieten, wenn Ausnahmen möglicherweise zu wesentlichen Leistungseinbußen führen.

Verwenden Sie keinen Fehlercode, weil Sie befürchten, dass Ausnahmen die Leistung beeinträchtigen.

Verringern Sie Leistungseinbußen durch den Entwurf. In diesem Thema werden zwei Entwurfsmuster beschrieben.

Das Tester-Ausführer-Muster empfiehlt sich für Member, die Ausnahmen in allgemeinen Szenarien auslösen können, um Leistungseinbußen aufgrund von Ausnahmen zu vermeiden.

Das Muster Prüfvorrichtung-Handelnd unterteilt wird ein Aufruf, der möglicherweise Ausnahmen in zwei Teile ausgelöst wurde: Tester und einen Ausführer. Der Tester führt einen Test auf den Zustand aus, der dazu führen kann, dass der Ausführer eine Ausnahme auslöst. Der Test wird direkt vor dem Code eingefügt, der die Ausnahme auslöst, und bietet dadurch einen Schutz vor der Ausnahme.

Im folgenden Codebeispiel wird der Ausführer-Teil dieses Musters veranschaulicht. Das Beispiel enthält eine Methode, die eine Ausnahme auslöst, wenn an sie einen null-Wert (Nothing in Visual Basic) übergeben wird. Wenn diese Methode häufig aufgerufen wird, kann sie sich negativ auf die Leistung auswirken.

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...
};

Im folgenden Codebeispiel wird der Tester-Teil dieses Musters veranschaulicht. Die Methode verhindert mit einem Test den Aufruf des Ausführers (ProcessMessage), wenn der Ausführer andernfalls eine Ausnahme auslöst.

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);
            }
        }
    }
};

Beachten Sie, dass sie potenzielle Racebedingungen berücksichtigen müssen, wenn Sie dieses Muster in einer Multithreadanwendung verwenden und der Test ein änderbares Objekt umfasst. Ein Thread kann den Zustand des änderbaren Objekts nach dem Test, doch vor der Ausführung des Ausführers ändern. Behandeln Sie diese Probleme mit Threadsynchronisierungsverfahren.

Verwenden Sie das TryParse-Muster für Member, die Ausnahmen in allgemeinen Szenarien auslösen können, um Leistungseinbußen aufgrund von Ausnahmen zu vermeiden.

Um das TryParse-Muster zu implementieren, geben Sie zwei unterschiedliche Methoden zum Ausführen einer Operation an, die in allgemeinen Szenarien Ausnahmen auslösen kann. Die erste Methode, X, führt die Operation aus und löst ggf. die Ausnahme aus. Die zweite Methode, TryX, löst keine Ausnahme aus, sondern gibt stattdessen einen Boolean-Wert zurück, der die erfolgreiche oder fehlgeschlagene Ausführung angibt. Die Rückgabe der von einem erfolgreichen Aufruf von TryX zurückgegebenen Daten erfolgt mit einem out-Parameter (ByRef in Visual Basic). Beispiele für dieses Muster sind die Parse-Methode und die TryParse-Methode.

Stellen Sie für jeden Member, der das TryParse-Muster verwendet, einen Member bereit, der eine Ausnahme auslöst.

Die Angabe nur der TryX-Methode ist fast niemals ein ordnungsgemäßer Entwurf, da dies ein Verständnis von out-Parametern erfordert. Außerdem tritt in den häufigsten Szenarien keine Leistungseinbuße durch Ausnahmen auf. Stellen Sie Methoden bereit, die in den häufigsten Szenarien einfach verwendet werden können.

Copyright für einzelne Teile 2005 Microsoft Corporation. Alle Rechte vorbehalten.

Copyright für einzelne Teile Addison-Wesley Corporation. Alle Rechte vorbehalten.

Weitere Informationen zu Entwurfsrichtlinien finden Sie unter „Framework-Entwurfs-Richtlinien: Idiome, Konventionen und Muster für wiederverwendbare .NET-Bibliotheken von Krzysztof Cwalina“ book und Brad Abrams, veröffentlicht von Addison-Wesley, 2005.

Siehe auch

Weitere Ressourcen

Entwurfsrichtlinien zum Entwickeln von Klassenbibliotheken

Entwurfsrichtlinien für Ausnahmen