Pergunta

Estou mantendo um aplicativo .NET 1.1 e uma das tarefas que recebi é garantir que o usuário não veja nenhuma notificação de erro hostil.

Eu adicionei manipuladores a Application.ThreadException e AppDomain.CurrentDomain.UnhandledException, que são chamados.Meu problema é que a caixa de diálogo de erro CLR padrão ainda é exibida (antes que o manipulador de exceções seja chamado).

Jeff fala sobre esse problema em seu blog aqui e aqui.Mas não há solução.Então, qual é a maneira padrão no .NET 1.1 de lidar com exceções não detectadas e exibir uma caixa de diálogo amigável?

A resposta de Jeff foi marcada como correta porque o link que ele forneceu contém as informações mais completas sobre como fazer o que é necessário.

Foi útil?

Solução

Ah, no Windows Forms você definitivamente deve conseguir fazê-lo funcionar.A única coisa que você deve observar são as coisas que acontecem em tópicos diferentes.

Eu tenho um artigo antigo do Code Project aqui que deve ajudar:

Tratamento de exceções amigável

Outras dicas

AppDomain.UnhandledException é um evento, não um manipulador de exceção global.Isso significa que, no momento em que ele é gerado, seu aplicativo já está indo pelo ralo e não há nada que você possa fazer a respeito, exceto limpar e registrar erros.

O que aconteceu nos bastidores foi o seguinte:A estrutura detectou a exceção, subiu a pilha de chamadas até o topo, não encontrou nenhum manipulador que pudesse se recuperar do erro e, portanto, não foi capaz de determinar se era seguro continuar a execução.Então, ele iniciou a sequência de desligamento e iniciou este evento como uma cortesia para você, para que você possa prestar sua homenagem ao seu processo já condenado.Isso acontece quando uma exceção não é tratada no thread principal.

Não existe uma solução única para esse tipo de erro.Você precisa colocar um manipulador de exceção real (um bloco catch) a montante de todos os locais onde esse erro ocorre e encaminhá-lo para (por exemplo) um método/classe de manipulador global que determinará se é seguro simplesmente relatar e continuar, com base em tipo e/ou conteúdo da exceção.

Editar:É possível desabilitar (= hackear) o mecanismo de relatório de erros integrado ao Windows para que a caixa de diálogo obrigatória "travar e gravar" não seja exibida quando o aplicativo for desativado.No entanto, isso se torna eficaz para todos os aplicativos do sistema, não apenas os seus.

O comportamento de exceção não tratada em um aplicativo .NET 1.x Windows Forms depende de:

  • O tipo de thread que lançou a exceção
  • Se ocorreu durante o processamento da mensagem da janela
  • Se um depurador foi anexado ao processo
  • A configuração do registro DbgJitDebugLaunchSetting
  • O sinalizador jitDebugging em App.Config
  • Se você substituiu o manipulador de exceções do Windows Forms
  • Se você lidou com o evento de exceção do CLR
  • A fase da lua

O comportamento padrão de exceções não tratadas é:

  • Se a exceção ocorrer no thread principal ao bombear mensagens de janela, ela será interceptada pelo manipulador de exceções do Windows Forms.
  • Se a exceção ocorrer no thread principal ao bombear mensagens de janela, o processo do aplicativo será encerrado, a menos que seja interceptado pelo manipulador de exceções do Windows Forms.
  • Se a exceção ocorrer em um thread manual, threadpool ou finalizador, ela será engolida pelo CLR.

Os pontos de contato para uma exceção não tratada são:

  • Manipulador de exceções do Windows Forms.
  • A opção de registro de depuração JIT DbgJitDebugLaunchSetting.
  • O evento de exceção não tratada do CLR.

O tratamento de exceções interno do Windows Form faz o seguinte por padrão:

  • Captura uma exceção não tratada quando:
    • a exceção está no thread principal e nenhum depurador anexado.
    • exceção ocorre durante o processamento de mensagens da janela.
    • jitDebugging = falso em App.Config.
  • Mostra a caixa de diálogo ao usuário e evita o encerramento do aplicativo.

Você pode desabilitar o último comportamento definindo jitDebugging = true em App.Config.Mas lembre-se de que esta pode ser sua última chance de impedir o encerramento de aplicativos.Portanto, a próxima etapa para capturar uma exceção não tratada é registrar-se no evento Application.ThreadException, por exemplo:

Application.ThreadException += new
Threading.ThreadExceptionHandler(CatchFormsExceptions);

Observe a configuração do registro DbgJitDebugLaunchSetting em HKEY_LOCAL_MACHINE\Software.NetFramework.Isso tem um dos três valores dos quais estou ciente:

  • 0:mostra a caixa de diálogo do usuário perguntando "depurar ou encerrar".
  • 1:permite a exceção para o CLR lidar.
  • 2:inicia o depurador especificado na chave de registro DbgManagedDebugger.

No Visual Studio, vá para o menu FerramentasOpçõesDepuraçãoJIT para definir esta chave como 0 ou 2.Mas o valor 1 geralmente é melhor na máquina do usuário final.Observe que essa chave de registro é acionada antes do evento de exceção não tratada do CLR.

Este último evento é sua última chance de registrar uma exceção não tratada.É acionado antes que seus blocos Finalmente sejam executados.Você pode interceptar este evento da seguinte maneira:

AppDomain.CurrentDomain.UnhandledException += new
System.UnhandledExceptionEventHandler(CatchClrExceptions);

Este é um aplicativo de console ou um aplicativo Windows Forms?Se for um aplicativo de console .NET 1.1, isso é, infelizmente, intencional - foi confirmado por um desenvolvedor da MSFT no segunda postagem do blog que você mencionou:

Aliás, na minha máquina 1.1, o exemplo do MSDN tem a saída esperada;só que a segunda linha só aparece depois de você anexar um depurador (ou não).Na v2, invertemos as coisas para que o evento UnhandledException seja acionado antes que o depurador seja anexado, o que parece ser o que a maioria das pessoas espera.

Parece que o .NET 2.0 faz isso melhor (graças a Deus), mas, honestamente, nunca tive tempo de voltar e verificar.

É um aplicativo Windows Forms.As exceções capturadas por Application.ThreadException funcionam bem e não recebo a caixa de exceção feia do .NET (OK terminar, Cancelar depurar?quem inventou isso??).

Eu estava recebendo algumas exceções que não estavam sendo detectadas por isso e acabei indo para o evento AppDomain.UnhandledException que estava causando problemas.Acho que detectei a maioria dessas exceções e estou exibindo-as em nossa bela caixa de erro agora.

Portanto, só espero que não haja outras circunstâncias que possam fazer com que as exceções não sejam capturadas pelo manipulador Application.ThreadException.

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