Compartilhar via


Exceções e desempenho

Observação

Esse conteúdo é reimpresso por permissão da Pearson Education, Inc. das Diretrizes de Design da Estrutura: Convenções, Idiomas e Padrões para Bibliotecas .NET Reutilizáveis, 2ª Edição. Essa edição foi publicada em 2008, e desde então o livro foi totalmente revisado na terceira edição. Algumas das informações nesta página podem estar desatualizadas.

Uma preocupação comum relacionada a exceções é que, se exceções forem usadas para código que falha rotineiramente, o desempenho da implementação será inaceitável. A preocupação é válida. Quando um membro lança uma exceção, seu desempenho pode ser ordens de magnitude mais lentas. No entanto, é possível obter um bom desempenho ao aderir estritamente às 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 Padrão de Tester-Doer ou o Padrão de Try-Parse, descrito nas próximas duas seções.

Padrão Testador-Executor

Às vezes, o desempenho de um membro gerador de exceções pode ser aprimorado ao dividir o membro em dois. Vamos examinar o Add método da ICollection<T> interface.

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

O método Add gera exceção se a coleção for somente leitura. Isso pode ser um problema de desempenho em cenários em que a chamada de método deve falhar com frequência. Uma das maneiras de atenuar 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 em nosso exemplo é a propriedade IsReadOnly, é conhecido como o testador. O membro usado para executar uma operação potencialmente geradora de exceção, o método Add em nosso exemplo, é chamado de executor.

✔️ CONSIDERE o padrão Testador-Executor para membros que podem gerar exceções em cenários comuns para evitar problemas de desempenho relacionados a exceções.

Padrão Tentar-Analisar

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

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 diferente da tentativa claramente definida, o membro ainda deverá lançar uma exceção correspondente.

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

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

✔️ FORNEÇA um membro que gera exceções para cada membro usando o padrão Tentar-Analisar.

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

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

Consulte também