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 8
Hans lo ha dicho!Exit(0)
hace un poco con algunos Win7 de 64 bits, el cambioExitCode
no ayuda ahora a usarProcess.GetCurrentProcess().Kill()
sin ningún problema, funcionaRespuestas:
Me puse en contacto con Microsoft sobre este problema y parecía haber valido la pena. Al menos me gustaría pensar que sí :). Aunque no obtuve una confirmación de una resolución de ellos, el grupo de Windows es difícil de contactar directamente y tuve que usar un intermediario.
Una actualización entregada a través de Windows Update resolvió el problema. El notable retraso de 2 segundos antes del bloqueo ya no está presente, lo que sugiere que se resolvió el punto muerto IsWindow (). Y el programa se cierra de manera limpia y confiable. La actualización instaló parches para Windows Defender, wdboot.sys, wdfilter.sys, tcpip.sys, rpcrt4.dll, uxtheme.dll, crypt32.dll y wintrust.dll
Uxtheme.dll es el pato extraño. Implementa la API de temas de estilos visuales y es utilizada por este programa de prueba. No puedo estar seguro, pero mi dinero está en eso como la fuente del problema. La copia en C: \ WINDOWS \ system32 tiene el número de versión 6.2.9200.16660, creado el 14 de agosto de 2013 en mi máquina.
Caso cerrado.
fuente
No sé por qué ya no funciona "más" , pero creo que
Environment.Exit
ejecuta finalizadores pendientes.Environment.FailFast
no lo haceEs posible que (por alguna extraña razón) tenga finalizadores pendientes extraños que deben ejecutarse después, lo que hace que esto suceda.
fuente
NativeWindow.ForceExitMessageLoop
atascada en código administrado o no administrado? ¿Está atascado o está ocupado esperando o esperando un mensaje u otra cosa?Esto no explica por qué está sucediendo, pero no llamaría
Environment.Exit
a un controlador de eventos de botón como su muestra; en cambio, cierre el formulario principal como se sugiere en la respuesta de René .En cuanto a un
AppDomain.UnhandledException
controlador, tal vez podría configurar enEnvironment.ExitCode
lugar de llamarEnvironment.Exit
.No estoy seguro de lo que estás tratando de lograr aquí. ¿Por qué desea devolver un código de salida de una aplicación de formularios Windows Forms? Normalmente, los códigos de salida son utilizados por las aplicaciones de consola.
¿Tienes un try / catch en el método Main? Para las aplicaciones de Windows Forms, siempre tengo un try / catch en el bucle de mensajes, así como los controladores de excepciones no controlados.
fuente
Application.Exit
lugar deEnvironment.Exit
.He encontrado el mismo problema en nuestra aplicación, lo hemos resuelto con la siguiente construcción:
fuente