Isso é algo que eu descobri há apenas alguns dias, e recebi a confirmação de que não está limitado apenas à minha máquina com essa pergunta .
A maneira mais fácil de reproduzi-lo é iniciando um aplicativo Windows Forms, adicione um botão e escreva este código:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
O programa falha após a execução da instrução Exit (). No Windows Forms, você recebe "Erro ao criar identificador de janela".
A ativação da depuração não gerenciada torna um pouco claro o que está acontecendo. O loop modal COM está em execução e permite que uma mensagem WM_PAINT seja entregue. Isso é fatal em um formulário descartado.
Os únicos fatos que reuni até agora são:
- Não se limita apenas à execução com o depurador. Isso também falha sem um. Um tanto ruim quanto, a caixa de diálogo de falha do WER aparece duas vezes .
- Não tem nada a ver com o testemunho do processo. A camada wow64 é bastante notória, mas uma compilação AnyCPU falha da mesma maneira.
- Não tem nada a ver com a versão .NET, 4.5 e 3.5 travar da mesma maneira.
- O código de saída não importa.
- Chamar Thread.Sleep () antes de chamar Exit () não o corrige.
- Isso acontece na versão de 64 bits do Windows 8 e o Windows 7 não parece ser afetado da mesma maneira.
- Este deve ser um comportamento relativamente novo, eu nunca vi isso antes. Não vejo atualizações relevantes fornecidas pelo Windows Update , embora o histórico de atualizações não seja mais preciso na minha máquina.
- Este é um comportamento grosseiramente violento. Você escreveria um código como esse em um manipulador de eventos para AppDomain.UnhandledException e ele trava da mesma maneira.
Estou particularmente interessado no que você poderia fazer para evitar esse acidente. Particularmente, o cenário AppDomain.UnhandledException me surpreende; não há muitas maneiras de encerrar um programa .NET. Observe que chamar Application.Exit () ou Form.Close () não é válido em um manipulador de eventos para UnhandledException, portanto, não são soluções alternativas.
ATUALIZAÇÃO: Mehrdad apontou que o encadeamento do finalizador pode ser parte do problema. Eu acho que estou vendo isso e também estou vendo algumas evidências pelo tempo limite de 2 segundos de que o CLR fornece ao thread do finalizador para concluir a execução.
O finalizador está dentro de NativeWindow.ForceExitMessageLoop (). Existe uma função IsWindow () Win32 que corresponde aproximadamente à localização do código, desloca 0x3c ao olhar o código da máquina no modo de 32 bits. Parece que IsWindow () está em um impasse. No entanto, não consigo obter um bom rastreamento de pilha para os internos, o depurador acha que a chamada P / Invoke acabou de retornar. Isso é difícil de explicar. Se você pode obter um melhor rastreamento de pilha, eu adoraria vê-lo. Meu:
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.ForceExitMessageLoop() + 0x3c bytes
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Finalize() + 0x16 bytes
[Native to Managed Transition]
kernel32.dll!@BaseThreadInitThunk@12() + 0xe bytes
ntdll.dll!___RtlUserThreadStart@8() + 0x27 bytes
ntdll.dll!__RtlUserThreadStart@8() + 0x1b bytes
Nada acima da chamada ForceExitMessageLoop, o depurador não gerenciado ativado.
This happens on the 64-bit version of Windows 8
Hans disse isso!
Exit(0)
um pouco atrás, com alguns 64bit Win7, mudando ExitCode
não ajudou usando agora Process.GetCurrentProcess().Kill()
sem qualquer problema ele funciona