Исключения и производительность
Обновлен: Ноябрь 2007
Генерация исключений может негативно сказаться на производительности. Для кода, исполнение которого регулярно завершается с ошибкой, можно разработать шаблоны для минимизации проблем производительности. В данном разделе описаны два шаблона, которые могут быть полезны, когда исключения существенно влияют на производительность.
Не используйте коды ошибки, так как исключения могут негативно повлиять на производительность.
При проектировании учитывайте вопросы производительности. В данном разделе описаны два шаблона.
Во избежание проблем производительности, связанных с исключениями, используйте шаблон Tester-Doer для членов, которые могут генерировать исключения в общих сценариях.
Шаблон Tester-Doer разделяет вызов, который может генерировать исключения, на две части: Tester и Doer. Фрагмент Tester выполняет проверку состояния, которое может привести к тому, что фрагмент Doer генерирует исключение. Проверка вставляется непосредственно перед кодом, который может генерировать исключение, не допуская генерации исключения.
В следующем примере кода показан фрагмент Doer этого шаблона. В примере содержится метод, который генерирует исключение, когда ему передается значение null (Nothing в Visual Basic). Если этот метод вызывается достаточно часто, это может негативно сказаться на производительности.
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...
}
В следующем примере кода показан фрагмент Tester этого шаблона. Этот метод использует проверку для предотвращения вызова фрагмента Doer (ProcessMessage), когда Doer может генерировать исключение.
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);
}
}
}
}
Обратите внимание, что следует учитывать возможность потенциального состояния гонки, если этот шаблон используется в многопоточном приложении, где проверка включает в себя изменяющийся объект. Поток может модифицировать состояние изменяющегося объекта после проверки, но перед вызовом фрагмента Doer. Для решения этих проблем следует использовать синхронизацию потоков.
Во избежание проблем производительности, связанных с исключениями, используйте шаблон TryParse для членов, которые могут генерировать исключения в общих сценариях.
В реализации шаблона TryParse имеются два различных метода для выполнения операции, которая может генерировать исключения в обычных сценариях. В первом методе, X, операция выполняется, и исключение генерируется по мере необходимости. Во втором методе, TryX, исключение не генерируется, но вместо этого возвращается значение Boolean, обозначающее успех или неудачу. Все данные, возвращаемые успешным вызовом TryX, возвращаются при помощи параметра out (ByRef в Visual Basic). Методы Parse и TryParse являются примерами этого шаблона.
Для каждого члена, использующего шаблон TryParse, предоставьте член генерации исключения.
Практически во всех случаях некорректно предоставлять только метод TryX, так как это требует понимания параметров out. Кроме того, влияние исключений на производительность не является проблемой для большинства обычных сценариев; следует предоставлять методы, которые легко использовать в большинстве обычных сценариев.
Охраняется авторским правом Copyright 2005 Microsoft Corporation. Все права защищены.
Охраняется авторским правом Copyright Addison-Wesley Corporation. Все права защищены.
Дополнительные сведения о руководствах по разработке см. в книге "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries", Krzysztof Cwalina and Brad Abrams, Addison-Wesley, 2005.