it-swarm-pt.tech

Como capturar TODAS as exceções / falhas em um aplicativo .NET

Possível duplicado:
. NET - Qual é a melhor maneira de implementar um "manipulador de capturar todas as exceções"

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

Em um aplicativo Win32, você pode capturar todas as possíveis exceções/falhas instalando vários manipuladores de exceção:

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

Qual é o equivalente no mundo .NET para que eu possa lidar com/registrar/silenciar todos os casos de erro possíveis?

39
DougN

Ao contrário do que outros publicaram, não há nada errado em capturar todas as exceções. O importante é lidar com todos adequadamente. Se você estiver com uma pilha excedente ou com pouca memória, o aplicativo deve ser desligado. Além disso, lembre-se de que as condições do OOM podem impedir que o manipulador de exceções funcione corretamente. Por exemplo, se o manipulador de exceções exibir uma caixa de diálogo com a mensagem de exceção, se você estiver com falta de memória, talvez não haja o suficiente para a exibição da caixa de diálogo. Melhor registrá-lo e desligar imediatamente.

Como outros mencionados, existem os eventos UnhandledException e ThreadException que você pode manipular para exceções de coleção que, de outra forma, poderiam ser perdidas. Em seguida, basta lançar um manipulador de exceções no loop principal (assumindo um aplicativo winforms).

Além disso, você deve estar ciente de que OutOfMemoryExceptions nem sempre são lançadas para condições de falta de memória. Uma condição OOM pode disparar todos os tipos de exceções, no seu código ou na estrutura, que não têm necessariamente nada a ver com o fato de que a condição subjacente real está sem memória. Eu sempre vi InvalidOperationException ou ArgumentException quando a causa subjacente está realmente sem memória.

27
Pete Davis

Você pode adicionar um manipulador de eventos ao evento AppDomain.UnhandledException e ele será chamado quando uma exceção for lançada e não capturada.

43
Juanma

Este artigo em codeproject do nosso anfitrião Jeff Atwood é o que você precisa. Inclui o código para capturar exceções não tratadas e práticas recomendadas para mostrar informações sobre a falha ao usuário.

11
Ricardo Amores

A classe Global.asax é sua última linha de defesa. Olhe para a:

protected void Application_Error(Object sender, EventArgs e)

método

10
Drejc

Esteja ciente de que algumas exceções são perigosas de capturar - ou, na maioria das vezes, inalcançáveis,

  • OutOfMemoryException: tudo o que você faz no manipulador de captura pode alocar memória (no lado gerenciado ou não gerenciado do CLR) e, assim, disparar outra OOM
  • StackOverflowException: dependendo de o CLR detectá-lo suficientemente cedo, você poderá ser notificado. No pior cenário, simplesmente mata o processo.
6
Peli

Embora capturar todas exceções sem o plano de manipulá-las adequadamente seja certamente uma má prática, acho que um aplicativo deve falhar de alguma maneira graciosa. Uma falha não deve assustar o usuário até a morte e, pelo menos, deve exibir uma descrição do erro, algumas informações para reportar 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 poder despejar em disco os dados do usuário e tentar recuperá-los (mas vejo que isso está pedindo muito).

Enfim, eu costumo usar:

AppDomain.CurrentDomain.UnhandledException
4
Dario Solera

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

4
Mendelt

Você também pode ir com o Application.ThreadException Event.

Uma vez eu estava desenvolvendo um aplicativo .NET em execução em um aplicativo baseado em COM; esse evento foi muito útil, pois AppDomain.CurrentDomain.UnhandledException não funcionou nesse caso.

3
petr k.

Eu acho que você não deve nem mesmo pegar todas as exceções, mas é melhor deixá-las mostradas ao usuário. A razão para isso é que você só deve capturar Exceções com as quais você pode realmente lidar. Se você se deparar com alguma exceção que faz com que o programa pare, mas ainda assim o pegue, isso pode causar problemas muito mais graves. Leia também FAQ: Por que o FxCop adverte contra captura (Exceção)? .

1
hangy

Esteja ciente de que capturar essas exceções não tratadas pode alterar os requisitos de segurança do seu aplicativo. Seu aplicativo pode parar de funcionar corretamente em certos contextos (quando executado a partir de um compartilhamento de rede etc.). Certifique-se de testar completamente.

1
Johnny Bravado

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

mas lembre-se de que as exceções nos encadeamentos secundários não são capturadas por esses manipuladores; use SafeThread para threads secundários, se necessário

0
Steven A. Lowe