Esto es algo que descubrí hace unos días, recibí la confirmación de que esta pregunta no solo se limita a mi máquina .
La forma más fácil de reproducirlo es iniciando una aplicación de formularios Windows Forms, agregue un botón y escriba este código:
private void button1_Click(object sender, EventArgs e) {
MessageBox.Show("yada");
Environment.Exit(1); // Kaboom!
}
El programa falla después de que se ejecuta la instrucción Exit (). En Windows Forms aparece "Error al crear el identificador de ventana".
Habilitar la depuración no administrada deja en claro lo que está sucediendo. El bucle modal COM se está ejecutando y permite que se entregue un mensaje WM_PAINT. Eso es fatal en una forma dispuesta.
Los únicos hechos que he reunido hasta ahora son:
- No se limita solo a ejecutar con el depurador. Esto también falla sin uno. También bastante mal, el cuadro de diálogo de bloqueo WER aparece dos veces .
- No tiene nada que ver con la brevedad del proceso. La capa wow64 es bastante notoria, pero una compilación AnyCPU se bloquea de la misma manera.
- No tiene nada que ver con la versión .NET, 4.5 y 3.5 se bloquean de la misma manera.
- El código de salida no importa.
- Llamar a Thread.Sleep () antes de llamar a Exit () no lo soluciona.
- Esto sucede en la versión de 64 bits de Windows 8, y Windows 7 no parece verse afectado de la misma manera.
- Este debería ser un comportamiento relativamente nuevo, no he visto esto antes. No veo actualizaciones relevantes entregadas a través de Windows Update , aunque el historial de actualizaciones ya no es preciso en mi máquina.
- Este es un comportamiento grosero. Escribiría un código como este en un controlador de eventos para AppDomain.UnhandledException, y se bloquea de la misma manera.
Estoy particularmente interesado en lo que podrías hacer para evitar este bloqueo. Particularmente el escenario AppDomain.UnhandledException me desconcierta; No hay muchas maneras de terminar un programa .NET. Tenga en cuenta que llamar a Application.Exit () o Form.Close () no son válidos en un controlador de eventos para UnhandledException, por lo que no son soluciones alternativas.
ACTUALIZACIÓN: Mehrdad señaló que el hilo finalizador podría ser parte del problema. Creo que estoy viendo esto y también estoy viendo algunas pruebas para el tiempo de espera de 2 segundos que el CLR le da al hilo finalizador para finalizar la ejecución.
El finalizador está dentro de NativeWindow.ForceExitMessageLoop (). Hay una función Win32 de IsWindow () que corresponde aproximadamente con la ubicación del código, compensa 0x3c cuando se mira el código de la máquina en modo de 32 bits. Parece que IsWindow () está bloqueado. Sin embargo, no puedo obtener un buen seguimiento de la pila para las partes internas, el depurador cree que la llamada P / Invoke acaba de regresar. Esto es difícil de explicar. Si puede obtener un mejor seguimiento de la pila, me encantaría verlo. Mía:
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 por encima de la llamada ForceExitMessageLoop, depurador no administrado habilitado.
This happens on the 64-bit version of Windows 8Hans lo ha dicho!
Exit(0)hace un poco con algunos Win7 de 64 bits, el cambio ExitCodeno ayuda ahora a usar Process.GetCurrentProcess().Kill()sin ningún problema, funciona