2009-03-04 12 views
19

En este momento, cuando el usuario quiere salir de mi solicitud, hago las pocas cosas que tengo que (es decir, de desconectarse del servidor, guardar los datos de usuario ...) y luego hago lo siguiente:¿Por qué no debería usar Process.GetCurrentProcess(). Kill() para salir de mi aplicación WinForm?

  • Salir de todos mis mainloops usando booleans
  • abortar los hilos aún en ejecución (generalmente, el hilo de sondeo de mi servidor)
  • amablemente llame a Application.Exit();

Esta toma unos segundos para salir, y no sirve a ningún propósito real (todo lo que ya se guarda en el servidor, por lo que no les importa lo que sucede allí)

Si utilizo este lugar, me consiguió la terminación inmediata sin inconveniente que puedo pensar:

System.Diagnostics.Process.GetCurrentProcess().Kill(); 

Por qué no me acabo de terminar mi proceso y dejar que el CLR caer el dominio de aplicación?

Sé que es importante deshacerse cuidadosamente de sus recursos compartidos (manejadores de archivos IO, etc.) (así que no responda :)), pero una vez hecho, ¿hay alguna razón real para salir limpiamente de mi aplicación?

+1

Supongo que los bloques finalmente no se procesarán en este caso, lo que puede causar errores inesperados en el futuro cuando otra persona mantiene el código. –

+0

@Hosam: Ese es un buen punto. ¿Por qué no lo publica como respuesta para que se pueda subir? – Brann

+0

@Brann: Listo. Gracias por la sugerencia. –

Respuesta

4

En primer lugar, creo que quiere decir Process.Kill(), no Process.TerminateProcess(). En segundo lugar, matar el proceso simplemente lo destruirá. Cualquier código de limpieza no se ejecutará y su aplicación no tendrá la posibilidad de cancelar la ejecución (por ejemplo, si el usuario tiene datos no guardados). Si estás contento con eso, ve por ello.

+1

De hecho, es Process.GetCurrentProcess(). Kill(); Arreglé mi publicación en consecuencia. ¡Gracias por notarlo! :) – Brann

4

¡Esa es una buena pregunta!

Érase una vez (hace más de diez años) escribí una aplicación VB6 que se colgó en la terminación debido a un error confirmado en WinINet OCX (o como se llame) debido al certificado particular utilizado en un servidor web estaba hablando con.

Sin ninguna forma de solucionar este error utilicé TerminateProcess y, por lo que sé, esta aplicación estuvo en uso en varios miles de máquinas durante varios años y nunca escuché ningún problema con respecto a este truco.

+0

Y aún tengo un caso de prueba en este momento que falla con el truco de Kill. Son dados cargados, de exactamente cuando el proceso fue asesinado, y exactamente lo que estaba haciendo el proceso, y exactamente lo que se supone que sucederá. Esta es la razón por la cual las bases de datos de ACID pasan por * tremendas longitudes * para asegurar las escrituras/rejugabilidad de datos, de modo que puedan cerrarse bruscamente en cualquier momento y no perder datos. Si el proceso atascado fue en cuclillas todo con datos críticos (en ese momento o más adelante), entonces por supuesto, nuclear; en realidad no es diferente de matar el proceso a través del explorador de procesos. – user2864740

1

Tenga en cuenta que si está escribiendo en una secuencia de archivo/red es posible que su escritura sea incompleta.

Si su aplicación está lista para tratar datos corruptos de esa manera, entonces no hay razón para no hacerlo. Sin embargo, si puede salir por otros medios, lo recomendaría.

12

Al matar el proceso, significa que finalmente no se ejecutarán los bloques, y probablemente ni siquiera critical finalizer objects, lo que en realidad puede ser crítico y puede causar la fuga de recursos a nivel del sistema. También puede causar errores inesperados en el futuro cuando otra persona mantiene el código, ya que ellos (o usted) tendrán que retorcer sus cabezas, teniendo que pensar que cada vez que escriban un bloque finalmente, se lo ejecutará.

+0

No se supone que el sistema operativo tenga pérdidas de recursos solo porque se haya cancelado un proceso. Pero esos bloques y finalizadores finalmente son un buen punto. – Qwertie

+1

@Qwertie Sí, pero a veces lo hace. Por ejemplo, una cámara puede dejarse abierta aunque la aplicación falle. Podría ser un error en el controlador, pero eso también es parte del "sistema". –

0

¿Por qué no utilizar System.Environment.Exit(int)? Parece que quieres hacer esto solo para guardar el código. Para mí, es mucho más claro ver que la llamada a Exit lo hace y tu apagado será más controlado, se ejecutarán Finalizers y Finalizers críticos.

+0

Environment.Exit (int) no garantiza la salida en caso de que el appdomain o código nativo subyacente salte a la familia de funciones WER/ReportFault. Incluso Kill() no es una garantía de finalización, ya que el bloqueo del kernel evitará que el proceso se cierre, pero Kill por lo general finaliza de forma instantánea, mientras que Exit permite la limpieza del programa. –

1

Cabe señalar que finalizers may actually be never executed, por lo que matar el proceso no es muy diferente de cualquier otra razón para omitir el código de finalización, como finalizadores lentos o un finalizador lanzando una excepción.

En general, no me preocuparía demasiado cerrar la aplicación en unos segundos, especialmente si oculta inmediatamente todas sus ventanas y "desaparece" para el usuario. Sin embargo, si el cierre demora decenas de segundos y es probable que el usuario ejecute la aplicación de nuevo y no es compatible con varias instancias, puede ser una buena idea llamar al Process.Kill.

Sé que algunas aplicaciones que tienen edades a finalizar, y espero ver algún día acaba matando brutalmente a sí mismos en lugar de hacer yo, el usuario, lo hacen (que es especialmente molesto en el reinicio del sistema operativo).

1

Utilizando bibliotecas de terceros sin forma de detectar sus errores o fugas, a veces la única forma de finalizarlo sin lanzar un MessageBox de error es matar el proceso.

Cuestiones relacionadas