Partilhar via


Exceções e desempenho

Nota

Este conteúdo é reimpresso com permissão da Pearson Education, Inc., a partir de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Essa edição foi publicada em 2008 e, desde então, o livro foi totalmente revisto na terceira edição. Algumas das informações nesta página podem estar desatualizadas.

Uma preocupação comum relacionada às exceções é que, se as exceções forem usadas para código que falha rotineiramente, o desempenho da implementação será inaceitável. Trata-se de uma preocupação válida. Quando um membro lança uma exceção, seu desempenho pode ser ordens de magnitude mais lento. No entanto, é possível alcançar um bom desempenho respeitando estritamente as diretrizes de exceção que não permitem o uso de códigos de erro. Dois padrões descritos nesta seção sugerem maneiras de fazer isso.

❌ NÃO use códigos de erro devido a preocupações de que exceções possam afetar negativamente o desempenho.

Para melhorar o desempenho, é possível usar o Tester-Doer Pattern ou o Try-Parse Pattern, descritos nas próximas duas seções.

Padrão Tester-Doer

Às vezes, o desempenho de um membro que lança exceções pode ser melhorado dividindo o membro em dois. Vamos olhar para o AddICollection<T> método da interface.

ICollection<int> numbers = ...
numbers.Add(1);

O método Add é lançado se a coleção for somente leitura. Isso pode ser um problema de desempenho em cenários em que se espera que a chamada de método falhe com frequência. Uma das maneiras de mitigar o problema é testar se a coleção é gravável antes de tentar adicionar um valor.

ICollection<int> numbers = ...
...
if (!numbers.IsReadOnly)
{
    numbers.Add(1);
}

O membro usado para testar uma condição, que no nosso exemplo é a propriedade IsReadOnly, é referido como o testador. O membro usado para executar uma operação de lançamento potencial, o Add método em nosso exemplo, é referido como o fazedor.

✔️ CONSIDERE o Tester-Doer Pattern para membros que podem lançar exceções em cenários comuns para evitar problemas de desempenho relacionados a exceções.

Padrão Try-Parse

Para APIs extremamente sensíveis ao desempenho, um padrão ainda mais rápido do que o Tester-Doer Pattern descrito na seção anterior deve ser usado. O padrão pede para ajustar o nome do membro para tornar um caso de teste bem definido uma parte da semântica do membro. Por exemplo, DateTime define um Parse método que lança uma exceção se a análise de uma cadeia de caracteres falhar. Ele também define um método correspondente TryParse que tenta analisar, mas retorna false se a análise não for bem-sucedida e retorna o resultado de uma análise bem-sucedida usando um out parâmetro.

public struct DateTime
{
    public static DateTime Parse(string dateTime)
    {
        ...
    }
    public static bool TryParse(string dateTime, out DateTime result)
    {
        ...
    }
}

Ao usar esse padrão, é importante definir a funcionalidade try em termos estritos. Se o membro falhar por qualquer motivo que não seja a tentativa bem definida, o membro ainda deve lançar uma exceção correspondente.

✔️ CONSIDERE o padrão Try-Parse para membros que podem lançar exceções em cenários comuns para evitar problemas de desempenho relacionados a exceções.

✔️ DO use o prefixo "Try" e o tipo de retorno booleano para métodos que implementam esse padrão.

✔️ DO fornece um membro que lança exceções para cada membro usando o padrão Try-Parse.

© Partes 2005, 2009 Microsoft Corporation. Todos os direitos reservados.

Reimpresso com permissão da Pearson Education, Inc., de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da Microsoft Windows Development Series.

Consulte também