2012-01-11 15 views
10

¿Qué?
Estoy desarrollando una aplicación de consola que necesita seguir funcionando las 24/7 No importa qué
¿Hay alguna manera de impedir que una aplicación multiproceso explote por alguna excepción no controlada que ocurre en "algún hilo en alguna parte"?
Mantener una aplicación en ejecución incluso si se produce una excepción no controlada

¿Por qué?
Por favor absténgase de dar lecciones como "debe gestionar todas sus excepciones", "esto nunca debería suceder" etc. Tengo mis razones: estamos en implementación de prueba y tenemos que mantener esto en ejecución, registrar excepciones y reiniciar todo hilos de nuevo. Si nada imprevisto ocurre y causa una excepción no controlada para ser lanzado, que debe ser detectado y algún método llamado para reiniciar todas las discusiones (atomicidad es imposible debido debido al diseño de nivel)

Dicho esto, soy consciente es posible que no sea posible reiniciar una aplicación desde "dentro" si se ha perdido debido a y la excepción no controlada (que ya implementé).

Hasta ahora, he usado Quartz.net's FileScan Job y un Flag File para detectar cosas así y reiniciar la aplicación desde el exterior. Pero esto suena raro para mí. Me gustaría encontrar algo más limpio y menos rápido y sucio.

DownVoting/Sniping Advertencia: SÉ que NO es posible "como está '".
Por favor, ser creativo/útil en lugar de bruscamente crítico y pensar en esto más como una "cuestión abierta"

+2

Entonces ... agrega una advertencia de "downvote" para su "pregunta abierta" y luego rechaza a todos los que intentan ayudarlo. Agradable ... –

+0

@EthanCabiac Disculpe por eso, su respuesta fue "no realmente" una respuesta por la razón que comenté primero. Después de tu edición eso fue diferente. Lo marcaré como una respuesta ya que esta es la opción que he publicado como una respuesta para mí mismo. Vamos a hacer las paces :) –

Respuesta

7

Es necesario asociar un controlador de un evento a otro UnhandledException en el dominio de aplicación actual:

AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler

Dentro del controlador, que tendrá que salvar de alguna manera lo suficientemente estado (en un archivo, base de datos, etc. .) para que la aplicación reiniciada pase a los nuevos hilos. A continuación, cree una instancia nueva de su aplicación de consola con una llamada al System.Diagnostics.Process.Start("MyConsoleApp.exe").

Tenga mucho cuidado al introducir la lógica para evitar un ciclo continuo de crash/restart/crash/restart.

+1

Esto ya está implementado. De ninguna manera esto ayudará a que algo se reinicie. La aplicación saldrá después de que el controlador haga su trabajo –

+1

@Mika: Si la forma en que implementó el manejador de excepciones no reinicia su programa, esa no es la falla del manejador de excepciones, es solo el comportamiento que no ha implementado en su UnhandledExceptionHandler. –

+0

@RobertP: Bueno, este es un punto MUY importante: el manejador de excepciones hace lo que se le dice, sí, PERO, corrígeme si estoy equivocado, la Aplicación ES finaliza justo después de que el controlador salga. Lo que hace mi punto: no permite que la aplicación se mantenga viva. –

11

Si se va a ejecutar 24/7 de todos modos, ¿por qué no write it as a Windows service y tomar ventaja de las opciones de recuperación integradas justo en windows?

Configuring Recovery Services

Este enfoque tiene la ventaja adicional de ser capaz de sobrevivir a un reinicio de la máquina, y se registrará averías/reinicia en los registros de sucesos del sistema.

+0

Realmente me gustaría evitar el uso de un servicio y mantener todo lo que no sea OS-Bound –

+1

¿Qué sistema operativo necesita para ser compatible? Parece extraño que hicieras programación que no sea de Windows en C#. – JohnFx

+1

@Mika: A continuación, separe las partes específicas que no son OS de las partes específicas del sistema operativo. Puede escribir múltiples objetos o bibliotecas. :) –

5
  • Usted no puede mantener un proceso en ejecución "no importa qué". ¿Qué pasa si el proceso es asesinado?
  • Usted no desea mantener un proceso en ejecución "no importa qué". ¿Qué pasa si el estado del proceso está dañado de tal manera que suceden "cosas malas" si sigue funcionando?
+1

Dije "Por favor absténgase de dar lecciones" :-) Me estoy acostumbrando a tales no respuestas en SOF pero siempre me pican. ¡No seas tan malditamente literal! por "No matter Matter What" Quiero decir "No importa Matter What Happens wrong in the program"! ADEMÁS, si el estado del proceso está dañado, recibiré una notificación por correo y lo veré en el servidor. Además, tengo mi mala lógica de administración de estado. Pero lo necesito para mantener las cosas en funcionamiento y ponerlas en escena por la noche si hay un problema. –

+3

@mika: Pediste ayuda sobre algo que obviamente no entiendes. Si no quiere una "lección", no pida ayuda. –

+1

Por alguna razón, toda esta publicación se siente como el comienzo de una publicación de blog de Raymond Chen. – JohnFx

2

Bueno, yo puedo pensar en un par de inconvenientes en la siguiente solución, pero es lo suficientemente bueno para mí por el momento:

static void Main() 
    { 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(OnUnhandledException); 
     CS = new ConsoleServer(); 
     CS.Run();    
    } 

    public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Exception exception = (Exception)e.ExceptionObject; 
     Logger.Log("UNHANDLED EXCEPTION : " + e.ExceptionObject.ToString()); 
     Process.Start(@"C:\xxxx\bin\x86\Release\MySelf.exe"); 
    } 
2

Si su uso de .Net 2.0 y superior, la respuesta que se puede' t.

En las versiones de .NET Framework 1.0 y 1.1, una excepción no controlada que se produce en un subproceso distinto del hilo principal aplicación es capturado por el tiempo de ejecución y por lo tanto no hacen que la aplicación terminar. Por lo tanto, es posible que el evento UnhandledException sea generado sin que la aplicación finalice. Comenzando con .NET Framework versión 2.0, este backstop para excepciones no controladas en hilos secundarios se eliminó, porque el efecto acumulativo de tales silencios fracasos incluyó degradación del rendimiento, datos dañados y bloqueos, todos los cuales fueron difíciles de depurar. Para obtener más información, , que incluye una lista de casos en los que el tiempo de ejecución no finaliza, consulte Excepciones en hilos gestionados.

Tomado de aquí:

http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

Si desea que la aplicación para sobrevivir, entonces necesitará muy agresivo try/catch alrededor de sus métodos para que nada escapa.

Aconsejaría usar un servicio de Windows mencionado por otros. Es lo mismo que una aplicación de consola, pero con un poco más de código de capa de servicio en la parte superior. Podrías llevar tu aplicación de consola y encubrirla a una aplicación de servicio fácilmente. Solo necesita anular los métodos service.start/pause/stop.

+0

Gracias por su instrucción sensata. Muy instructivo de hecho. –

Cuestiones relacionadas