Compartir a través de


Excepciones y rendimiento

Iniciar excepciones puede tener un impacto negativo en el rendimiento. Para el código que produce errores repetidamente, puede utilizar modelos de diseño para minimizar los problemas de rendimiento. Este tema describe dos modelos de diseño que son útiles cuando las excepciones podrían ejercer un impacto significativo en el rendimiento.

No utilice códigos de error si le preocupa que las excepciones podrían afectar negativamente al rendimiento.

Utilice el diseño para mitigar los problemas de rendimiento. En este tema se explican dos modelos.

Considere la posibilidad de utilizar el modelo prueba-acción (Tester-Doer) para los miembros que pueden iniciar excepciones en escenarios comunes para evitar los problemas de rendimiento relacionados con las excepciones.

El modelo de Evaluador-Autor divide una llamada que podría producir excepciones en dos partes: un evaluador y un autor. La parte de prueba realiza una comprobación del estado que puede hacer que la parte de acción inicie una excepción. La prueba se inserta justo antes del código que inicia la excepción, protegiendo así contra la aparición de la excepción.

El ejemplo de código siguiente muestra la mitad de acción de este modelo. El ejemplo contiene un método que inicia una excepción cuando se le pasa un valor null (Nothing en Visual Basic). Si se llama a este método a menudo, podría ejercer un impacto negativo en el rendimiento.

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

El ejemplo de código siguiente muestra la parte de prueba de este modelo. El método utiliza una prueba para evitar la llamada a la parte de acción (ProcessMessage) cuando la acción iniciaría una excepción.

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

Observe que debe prever las posibles condiciones de carrera si utiliza este modelo en una aplicación multiproceso en la que la prueba implica un objeto mutable. Un subproceso puede cambiar el estado del objeto mutable después de la comprobación pero antes de que se ejecute la acción. Utilice las técnicas de sincronización de subprocesos para tratar estos problemas.

Considere la posibilidad de utilizar el modelo (TryParse) para los miembros que pueden iniciar excepciones en escenarios comunes para evitar los problemas de rendimiento relacionados con las excepciones.

Para implementar el modelo TryParse, se proporcionan dos métodos distintos de realizar una operación que puede iniciar excepciones en escenarios comunes. El primer método, X, efectúa la operación e inicia la excepción cuando corresponde. El segundo método, TryX, no inicia la excepción, pero en su lugar devuelve un valor Boolean que indica si se ha realizado correctamente o ha dado error. Los datos devueltos por una llamada correcta a TryX se devuelven utilizando un parámetro out (ByRef en Visual Basic). Los métodos Parse y TryParse son ejemplos de este modelo.

Proporcione un miembro que inicie excepciones para cada miembro utilizando el modelo TryParse.

Casi nunca es correcto que el diseño proporcione sólo el método TryX porque requiere comprender los parámetros out. Además, el impacto que tienen las excepciones en el rendimiento no es un problema en los escenarios más comunes; debería proporcionar métodos fáciles de utilizar en los escenarios más comunes.

Portions Copyright 2005 Microsoft Corporation. Reservados todos los derechos.

Portions Copyright Addison-Wesley Corporation. Reservados todos los derechos.

Para obtener más información sobre las directrices de diseño, consulte “las instrucciones de diseño de Framework: Convenciones, frases realizadas y modelos para libro de bibliotecas reutilizables de .NET” de Krzysztof Cwalina y Brad Abrams, publicados por Addison-Wesley, 2005.

Vea también

Otros recursos

Instrucciones de diseño para desarrollar bibliotecas de clases

Instrucciones de diseño de excepciones