예외 및 성능

예외를 throw하면 성능에 부정적인 영향을 줄 수 있습니다. 지속적으로 실패하는 코드의 경우 디자인 패턴을 사용하여 성능 문제를 최소화할 수 있습니다. 이 항목에서는 예외가 성능에 중대한 영향을 미치는 경우 유용한 두 가지 디자인 패턴에 대해 설명합니다.

예외가 성능에 부정적인 영향을 줄 수 있으므로 오류 코드를 사용하지 않습니다.

디자인을 사용하여 성능 문제를 줄일 수 있습니다. 이 항목에서는 두 가지 패턴에 대해 설명합니다.

일반적인 시나리오에서 예외를 throw할 수 있는 멤버의 경우 예외와 관련된 성능 문제를 피하기 위해 Tester-Doer 패턴을 사용할 수 있습니다.

테스터 두려움 패턴 구분 두 부분으로 예외를 throw 할 수 있습니다 호출이 됩니다. 테스터와는 두려움입니다. Tester는 Doer가 예외를 throw할 수 있는 상태에 대한 테스트를 수행합니다. 예외를 throw하는 코드 바로 앞에 테스트가 삽입되고 이로 인해 예외로부터 보호할 수 있습니다.

다음 코드 예제에서는 이 패턴의 Doer 부분을 보여 줍니다. 이 예제에는 null(Visual Basic의 경우 Nothing) 값이 전달되면 예외를 throw하는 메서드가 포함되어 있습니다. 이 메서드를 자주 호출하면 성능에 부정적인 영향을 줄 수 있습니다.

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

다음 코드 예제에서는 이 패턴의 Tester 부분을 보여 줍니다. 이 메서드는 Doer가 예외를 throw하는 경우 테스트를 사용하여 Doer(ProcessMessage)가 호출되지 않도록 합니다.

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

테스트에 변경 가능한 개체가 사용되는 다중 스레드 응용 프로그램에서 이 패턴을 사용하는 경우 잠재적인 경합 상태를 지정해야 합니다. 테스트 후에 Doer가 실행되기 전에 스레드에서 변경 가능한 개체의 상태를 변경할 수 있습니다. 스레드 동기화 기술을 사용하여 이러한 문제를 해결합니다.

일반적인 시나리오에서 예외를 throw할 수 있는 멤버의 경우 예외와 관련된 성능 문제를 피하기 위해 TryParse 패턴을 사용할 수 있습니다.

TryParse 패턴을 구현하기 위해 일반적인 시나리오에서 예외를 throw할 수 있는 연산을 수행하도록 두 가지 다른 메서드를 제공합니다. 첫 번째 메서드인 X는 연산을 수행하고 적절한 경우에 예외를 throw합니다. 두 번째 메서드인 TryX는 예외를 throw하지 않고 대신 성공이나 실패를 나타내는 Boolean 값을 반환합니다. TryX를 성공적으로 호출하여 반환되는 모든 데이터는 out(Visual Basic의 경우 ByRef) 매개 변수를 사용하여 반환됩니다. ParseTryParse 메서드는 이러한 패턴의 예제입니다.

TryParse 패턴을 사용하여 각 멤버에 예외를 throw하는 멤버를 제공합니다.

TryX 메서드를 사용하려면 out 매개 변수를 이해해야 하므로 이 메서드만 제공하는 것이 올바른 디자인이 아닐 수도 있습니다. 또한 예외가 성능에 미치는 영향은 대부분의 시나리오에서 문제가 되지 않습니다. 따라서 대부분의 일반적인 시나리오에서 사용하기 쉬운 메서드를 제공해야 합니다.

Portions Copyright 2005 Microsoft Corporation. All rights reserved.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

디자인 지침에 자세한 내용은 참조를 "Framework 디자인 지침: 규칙, 숙어, 및 재사용에 대 한 패턴입니다.NET 라이브러리"도 서 Krzysztof Cwalina와 Brad Abrams, 게시 Addison-wesley, 2005.

참고 항목

기타 리소스

클래스 라이브러리 개발을 위한 디자인 지침

예외 디자인 지침