Por que o Environment.Exit () não finaliza mais o programa?

Isso é algo que eu descobri há poucos dias, eu tenho a confirmação de que não é apenas limitado a minha máquina deessa questão.

A maneira mais fácil de reproduzir é iniciar um aplicativo do Windows Forms, adicionar um botão e escrever este código:

    private void button1_Click(object sender, EventArgs e) {
        MessageBox.Show("yada");
        Environment.Exit(1);         // Kaboom!
    }

O programa falhadepois de a instrução Exit () é executada. No Windows Forms, você recebe "Erro ao criar o identificador da janela".

Ativar a depuração não gerenciada deixa um pouco claro o que está acontecendo. oCOM loop modal está sendo executado e permite que uma mensagem WM_PAINT seja entregue. Isso é fatal em uma forma disposta.

Os únicos fatos que eu recolhi até agora são:

Não se limita apenas a executar com o depurador. Isso também falha sem um. Bem pior, a caixa de diálogo do acidente do WER apareceduas vezes.Não tem nada a ver com a gravidade 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 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 não vi isso antes. Não vejo atualizações relevantes fornecidas por meio deatualização do Windows, embora o histórico de atualizações não seja mais preciso em minha máquina.Isso está quebrando o comportamento grosseiramente. Você escreveria código como este em um manipulador de eventos para AppDomain.UnhandledException, e trava da mesma maneira.

Estou particularmente interessado no que você poderia fazer para evitar esse acidente. Particularmente, o cenário AppDomain.UnhandledException me entope; não há muitas maneiras de encerrar um programa .NET. Por favor, note que chamar Application.Exit () ou Form.Close () não são válidos em um manipulador de eventos para UnhandledException, portanto, eles não são soluções alternativas.

ATUALIZAÇÃO: Mehrdad apontou que o thread finalizador poderia ser parte do problema. Eu acho que estou vendo isso e também estou vendo algumas evidências para o tempo limite de 2 segundos que o CLR dá o segmento finalizador para concluir a execução.

O finalizador está dentro de NativeWindow.ForceExitMessageLoop (). Há uma função Win32 IsWindow () lá que corresponde aproximadamente com a localização do código, o deslocamento 0x3c quando se olha para o código de máquina no modo de 32 bits. Parece que IsWindow () está em deadlocking. Não consigo obter um bom rastreamento de pilha para os internos, no entanto, o depurador acha que oP / Invoke chamada apenas retornou. Isso é difícil de explicar. Se você puder obter um melhor rastreamento de pilha, então eu adoraria ver isso. 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, depurador não gerenciado ativado.