Qual é a diferença entre Application.ThreadException e AppDomain.CurrentDomain.UnhandledException?

107

Tudo bem, esta é fácil:

  • Qual é a diferença entre Application.ThreadExceptione
    AppDomain.CurrentDomain.UnhandledException?

  • Eu preciso lidar com ambos?

Obrigado!

JohnIdol
fonte

Respostas:

98

Application.ThreadException é específico para Windows Forms. Winforms executa manipuladores de eventos em resposta a mensagens enviadas a ele pelo Windows. O evento Click, por exemplo, tenho certeza que você os conhece. Se tal manipulador de eventos lançar uma exceção, então há um back-stop dentro do loop de mensagem do WinForms que captura essa exceção.

Esse backstop dispara o evento Application.ThreadException . Se você não substituí-lo, o usuário obterá um ThreadExceptionDialog . O que permite que ele ignore a exceção e continue executando seu programa. Não é uma boa ideia aliás.

Você pode desativar esse comportamento chamando Application.SetUnhandledExceptionMode () no método Main () em Program.cs. Sem esse backstop no lugar, o normal acontece quando um thread morre de uma exceção não tratada: AppDomain.UnhandledException é acionado e o programa termina.

Fwiw: "ThreadException" foi uma escolha de nome muito ruim. Não tem nada a ver com tópicos.

Hans Passant
fonte
E como impedir que o aplicativo WinForms travar na ocorrência de Application.ThreadException. Eu levantei uma questão para isso [aqui ] com meu pequeno código C #.
Mahesha999 de
2
Eu sempre li isso como exceção de thread de aplicativo, uma vez que winforms é vinculado a um único thread.
Gusdor
36

Da fonte :

Em aplicativos que usam Windows Forms, exceções não tratadas no thread do aplicativo principal fazem com que o Application.ThreadException evento seja gerado. Se esse evento for tratado, o comportamento padrão é que a exceção não tratada não encerra o aplicativo, embora o aplicativo seja deixado em um estado desconhecido. Nesse caso, o UnhandledException evento não é gerado. Esse comportamento pode ser alterado usando o arquivo de configuração do aplicativo ou usando o Application.SetUnhandledExceptionModemétodo para alterar o modo UnhandledExceptionMode.ThrowExceptionantes de o ThreadException manipulador de eventos ser conectado. Isso se aplica apenas ao thread principal do aplicativo. O UnhandledException evento é gerado para exceções não tratadas lançadas em outros threads.

A partir do Visual Studio 2005 , a estrutura do aplicativo Visual Basic fornece outro evento para exceções não tratadas no thread principal do aplicativo - WindowsFormsApplicationBase.UnhandledException. Este evento tem um objeto de argumentos de evento com o mesmo nome do objeto de argumentos de evento usado por AppDomain.UnhandledException, mas com propriedades diferentes. Em particular, este objeto de argumentos de evento tem uma ExitApplicationpropriedade que permite que o aplicativo continue em execução, ignorando a exceção não tratada (e deixando o aplicativo em um estado desconhecido). Nesse caso, o evento AppDomain.UnhandledException não é gerado.

Application.ThreadExceptionpode ser capturado e o aplicativo pode continuar (em geral não é uma boa ideia, mas para o aplicativo, como executar algumas ações periodicamente, essa é uma boa solução).

Para capturar exceções que ocorrem em threads não criados e pertencentes a Windows Forms, use o AppDomain.UnhandledException. Ele permite que o aplicativo registre informações sobre a exceção antes que o manipulador padrão do sistema relate a exceção ao usuário e encerre o aplicativo.
O tratamento dessa exceção não impede que o aplicativo seja encerrado.
O máximo que pode ser feito (os dados do programa podem ser corrompidos quando as exceções não são tratadas) é salvar os dados do programa para recuperação posterior. Depois disso, o domínio do aplicativo é descarregado e o aplicativo é encerrado.

A partir do .NET 4 , esse evento não é gerado para exceções que corrompem o estado do processo, como estouro de pilha ou violações de acesso, a menos que o manipulador de eventos seja crítico para a segurança e tenha o HandleProcessCorruptedStateExceptionsAttribute atributo.

Para obter mais detalhes, consulte MSDN .

serio
fonte
18

OK - eu tinha na minha frente, este pedaço de código do msdn é bastante autoexplicativo:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}
JohnIdol
fonte
3
isso está em contraste com a outra resposta de serhio quando ele diz: UnhandledExceptionMode.ThrowException deve ser definido antes que o manipulador de eventos ThreadException seja conectado. Não tenho certeza se a ordem realmente importa ...
Davide Piras
@DavidePiras sim, e há algo mais obscuro. SetUnhandledException parece não fazer diferença no meu caso.
nawfal
0

Bem, o fato é que, ThreadExceptionocorre devido a um problema com o seu segmento, o Unhandled Exceptioné disparado se o código lançar uma exceção que não é tratada.

A maneira mais fácil de causar o segundo é criar um aplicativo sem tentar ... capturar blocos e lançar uma exceção.

Agora, se você precisa de seguro, pode lidar com os dois; no entanto, se você capturar e manipular o seu exceptionscorretamente, não precisará do UnhandledExceptionmanipulador, pois é quase como um pega-tudo.

Joshua Cauble
fonte
obrigado - o que eu não estava muito claro foi se manipulando UnhandledException eu capturaria também ThreadException - o que parece não ser o caso
JohnIdol