2009-08-14 10 views
10

Ejecutamos una aplicación de consola C# que inicia varios subprocesos para hacer el trabajo. La función principal es como la siguiente:La aplicación C# finaliza inesperadamente

try 
{ 
    DoWork(); 
} 
catch (Exception err) 
{ 
    Logging.Log("Exception " + err.ToString()); 
} 
Logging.Log("Finished"); 

la función DoWork() lee nuevos puestos de trabajo a partir de una base de datos y genera subprocesos para procesar un elemento de trabajo cada uno. Desde la semana pasada, la aplicación comenzó a desaparecer misteriosamente. Desaparece de la lista de procesos y no hay ninguna entrada en los registros de eventos. El archivo de registro muestra el trabajo hasta cierto punto: no registra una excepción o la línea "Finalizada".

¿Alguna pista sobre cómo una aplicación C# puede desaparecer así?

EDIT: Hilos se crean como:

new Thread(SomeObj.StartFunc).Start(); 

Algunas de las desapariciones se producen cuando no hay temas se están ejecutando.

P.S. Instalamos DebugDiag con una regla para crear un volcado de emergencia cada vez que nuestro programa se bloqueaba. No creó ningún archivo de volcado cuando el proceso desapareció.

+0

Realmente podríamos hacer con un poco más detalle acerca de lo que hay en el método DoWork ... –

+0

¿Qué hacer después de DoWork creación e inicio de las discusiones? ¿Entra en un ciclo infinito, sale inmediatamente, intenta unirse a los hilos de fondo, o qué? –

+0

Entra en un ciclo infinito. Los subprocesos de fondo actualizan su estado en una matriz que está protegida con instrucciones lock {}. Cuando se realiza un subproceso, elimina su propia entrada de la matriz. – Andomar

Respuesta

9

¿Cuál es la identidad que está utilizando para ejecutar la aplicación de la consola?

También es posible que desee utilizar SetConsoleCtrlHandler para capturar la consola de eventos. Mira esto blog para más detalles. Tuvimos un problema similar cuando la aplicación de la consola se ejecutaba en una cuenta de servicio, ocasionalmente se terminaba. No estoy seguro de si esto es con lo que te estás metiendo. Avísame que puedo publicar un código.

ACTUALIZACIÓN: Parece que eres escenario se asemeja a lo que habíamos visto. En el controlador de eventos de la consola, debe verificar el evento LogOff y devolver true. Mira este artículo KB

public static void inputHandler(ConsoleCtrl.ConsoleEvent consoleEvent) 
{ 
    if (ConsoleEvent == ConsoleCtrl.ConsoleEvent.CtrlLogOff) 
     return true; 
    return false; 
} 
+0

Se está ejecutando como una tarea programada mediante una cuenta con privilegios administrativos. ¡Agregué el controlador y lo modifiqué para registrar eventos, dejándolo funcionar por un tiempo para ver si funciona! – Andomar

+2

He agregado el registro y el evento CtrlLogOff es de hecho lo que hace que la tarea programada salga. Problema resuelto, aunque aún nos gustaría saber de dónde viene el evento CtrlLogOff. – Andomar

+5

¿Cómo puede devolver un booleano desde una función vacía? – Ruud

9

Necesita tener un bloque catch similar en el nivel superior de la función que funciona cada hilo. Si hay una excepción no detectada en un hilo, matará a la aplicación, el bloque catch en el hilo principal no ayudará.

+0

El hilo tiene un bloque try/catch en su función de nivel superior. – Andomar

3

quizás es la función Logging.Log que arroja su excepción?

+0

La función de registro es simple y hay mucho espacio en disco disponible. El programa mantiene abierto un único StreamWriter mientras se ejecuta, y protege el acceso a él con una sección de bloqueo {}. – Andomar

3

Un programa de consola se cierra cuando sale la función principal. Como DoWork acaba de engendrar algunos hilos, devuelve el control a la principal de inmediato, y como Main no tiene nada más que hacer, sale y el programa finaliza. En este momento, los hilos generados por DoWork también se eliminan.

El hecho de que funcionó significa que hay algo en DoWork() para esperar en esos hilos que ahora vuelve inmediatamente (está roto) o esa parte todavía funciona pero un hilo que tardaba mucho en regresar ahora aborta y regresa de inmediato.

+0

La función DoWork() no regresa antes de que todo el trabajo haya terminado y todos los hilos se hayan cerrado. El programa funcionó bien durante años y procesó más de un millón de elementos de trabajo. – Andomar

+0

Espera ... ¿Creí que solo se eliminarían los hilos de fondo cuando salga la aplicación que los generó? – Will

+0

@Will: creo que ese es el comportamiento de un servicio de Windows. Otras aplicaciones de Windows funcionan como Joel describe – Andomar

2

He logrado hacer que los programas desaparezcan sin dejar rastro de una manera similar a usted (sin rastros de excepción, sin mensajes de registro de terminación) en el pasado. Casi todo el tiempo estuvo relacionado con matar a la pila (el nombre de este sitio web siempre me recuerda).

¿Es posible que de repente trates de procesar muchos más datos de lo habitual, o que utilices rutinas de reentrantes, o que seas "inteligente" con los punteros?

DESCARGO DE RESPONSABILIDAD: mi experiencia fue con una aplicación Win32 C++, no con C#.

2

¿Podría ser una pérdida de memoria? Si su aplicación ocupa demasiada memoria, Windows la matará. Puede verificar cuánta memoria está usando: si crece con el tiempo, es posible que tenga una pérdida de memoria.

Otra posibilidad es que en algún lugar, tenga un código que llame a Environment.Exit(). Pruebe una búsqueda de texto completo a través de su código para verificarlo, ¡nunca se sabe!

+0

Gracias por los consejos. El uso de memoria no parece crecer, y la función Salir() fue una de las primeras cosas que comprobamos :) – Andomar

5

Es posible que uno de los hilos que el método DoWork está generando esté lanzando una excepción. El comportamiento predeterminado en este caso es que el proceso finalice. Puede evitar que esto suceda utilizando el evento AppDomain.UnhandledException para anular el comportamiento predeterminado.

2

tener cuidado, hay algunas excepciones, que no pueden ser capturadas: OutOfMemoryException, StackOverflowException, por lo tanto, su programa va a morir terriblemente, pero en silencio.

+0

Sí, pero esperaba que esto activara DebugDiag y registrara un volcado de emergencia. – Andomar

+0

AFAIK 'OutOfMemoryException' se puede atrapar. – CodesInChaos

Cuestiones relacionadas