Pergunta

Duplicate possíveis:
.NET - Qual é a melhor maneira de implementar um “capturar todas as exceções manipulador”

Eu tenho um aplicativo console app NET que está falhando e exibir uma mensagem para o usuário. Todo o meu código está em um bloco try{<code>} catch(Exception e){<stuff>}, mas ainda erros são ocasionalmente exibido.

Em um aplicativo Win32, você pode capturar todas as exceções possíveis / trava através da instalação de vários manipuladores de exceção:

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

O que é o equivalente no mundo .NET para que eu possa lidar com / log / acalmar todos os casos possíveis de erro?

Foi útil?

Solução

Ao contrário do que alguns outros já publicados, não há nada errado captura todas as exceções. O importante é lidar com todos eles de forma adequada. Se você tem um estouro de pilha ou fora de condição de memória, o aplicativo deve desligar para eles. Além disso, mantenha em mente que as condições OOM pode impedir que o manipulador de exceção de funcionar corretamente. Por exemplo, se o manipulador de exceção mostra uma janela com a mensagem de exceção, se você estiver fora de memória, pode não ser suficiente esquerda para a exibição de diálogo. Melhor para registrá-lo e encerrar imediatamente.

Como os outros mencionados, há os eventos UnhandledException e ThreadException que você pode manipular a exceções de coleta que poderiam se perder. Em seguida, basta jogar um manipulador de exceção em torno de seu loop principal (supondo que um aplicativo winforms).

Além disso, você deve estar ciente de que OutOfMemoryExceptions nem sempre são jogados para fora de condições de memória. Uma condição OOM pode acionar todos os tipos de exceções, no seu código, ou no quadro, que não necessariamente tem nada a ver com o fato de que a condição real subjacente está sem memória. Tenho visto freqüentemente InvalidOperationException ou ArgumentException quando a causa subjacente é realmente falta de memória.

Outras dicas

Você pode adicionar um manipulador de evento para evento AppDomain.UnhandledException, e ele vai ser chamado quando uma exceção é lançada e não pegou.

Este artigo em codeproject por nosso anfitrião Jeff Atwood é o que você precisa. Inclui o código para pegar exceções não tratadas e as melhores práticas para mostrar informações sobre o acidente para o usuário.

O Global.asax classe é a sua última linha de defesa. Olhada em:

protected void Application_Error(Object sender, EventArgs e)

método

Esteja ciente de que alguma exceção é perigoso para pegar - ou principalmente uncatchable,

  • OutOfMemoryException: qualquer coisa que você fazer no manipulador catch pode alocar memória (no lado gerenciado ou não da CLR) e, assim, provocar um outro OOM
  • StackOverflowException: dependendo se o CLR detectado suficientemente cedo, você pode ser notificado. Pior cenário, ele simplesmente mata o processo.

Você pode usar o AppDomain.CurrentDomain.UnhandledException para obter um evento.

Apesar de captura todas exceções sem o plano para lidar com eles corretamente é certamente uma má prática, eu acho que um aplicativo deve falhar de alguma forma graciosa. Um acidente não deve assustar o usuário à morte, e, pelo menos, ele deve exibir uma descrição do erro, algumas informações para relatório ao material de suporte técnico, e, idealmente, um botão para fechar o aplicativo e reiniciá-lo. Em um mundo ideal, o aplicativo deve ser capaz de despejar no disco os dados do usuário, e, em seguida, tentar recuperá-lo (mas eu vejo que isso é pedir demais).

De qualquer forma, eu costumo usar:

AppDomain.CurrentDomain.UnhandledException

Você também pode ir com Application.ThreadException evento.

Uma vez eu estava desenvolvendo um aplicativo .NET em execução dentro de uma aplicação baseada em COM; Este evento foi o muito útil, como AppDomain.CurrentDomain.UnhandledException não funcionou neste caso.

Eu acho que você deve, antes, nem mesmo pegar todos Exceção mas melhor deixá-los ser mostrado para o usuário. A razão para isto é que você só deve capturar exceções que você pode realmente manipular. Se você tiver alguma exceção que faz com que o programa para parar, mas ainda pegá-lo, isso pode causar problemas muito mais graves. Leia também FAQ: Por que FxCop alertar contra catch (Exception)? .

Esteja ciente de que a captura dessas exceções não tratadas podem alterar os requisitos de segurança do aplicativo. O aplicativo pode parar de funcionar corretamente em certos contextos (quando executado a partir de um compartilhamento de rede, etc.). Certifique-se de testar exaustivamente.

não faz mal usar tanto AppDomain.CurrentDomain.UnhandledException Application.ThreadException

Mas tenha em mente que as exceções em segmentos secundários não são capturados por esses manipuladores; usar SafeThread para threads secundários, se necessário

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top