El servicio Windows .NET con el cronómetro deja de responder

Tengo un servicio de Windows escrito en c #. Tiene un temporizador dentro, que dispara algunas funciones de forma regular. Entonces el esqueleto de mi servicio:

public partial class ArchiveService : ServiceBase { Timer tickTack; int interval = 10; ... protected override void OnStart(string[] args) { tickTack = new Timer(1000 * interval); tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed); tickTack.Start(); } protected override void OnStop() { tickTack.Stop(); } private void tickTack_Elapsed(object sender, ElapsedEventArgs e) { ... } } 

Funciona por un tiempo (como 10-15 días) luego se detiene. Quiero decir que el servicio se muestra como en ejecución, pero no hace nada. Realizo algunos registros y el problema puede ser el temporizador, porque después del intervalo no llama a la función tickTack_Elapsed.

Estaba pensando en reescribirlo sin un temporizador, usando un bucle infinito, que detiene el procesamiento por el tiempo que configuré. Esta tampoco es una solución elegante y creo que puede tener algunos efectos secundarios con respecto a la memoria.

El temporizador se usa desde el espacio de nombres System.Timers, el entorno es Windows 2003. Utilicé este enfoque en dos servicios diferentes en servidores diferentes, pero ambos están produciendo este comportamiento (es por eso que pensé que de alguna manera estaba conectado a mi código o el marco mismo).

¿Alguien experimentó este comportamiento? ¿Qué puede estar mal?


Editar:

Edité ambos servicios. Uno consiguió un buen try-catch en todas partes y más logging. El segundo tiene un temporizador de recreación de forma regular. Ninguno de ellos se detuvo desde entonces, así que si esta situación continúa por otra semana, cerraré esta pregunta. Gracias por todos hasta ahora.


Editar:

Cerré esta pregunta porque no pasó nada. Quiero decir que hice algunos cambios, pero esos cambios no son realmente relevantes en este asunto y ambos servicios se están ejecutando sin ningún problema desde entonces. Por favor, márquelo como “Cerrado para ya no relevante”.

Al igual que muchos de los encuestados han señalado que las excepciones se tragan por el temporizador. En mis servicios de Windows utilizo System.Threading.Timer. Tiene el método Change (…) que le permite iniciar / detener ese temporizador. El posible lugar para la excepción podría ser un problema de reentrada, en el caso de que tickTack_Elapsed se ejecute más tiempo que el período del temporizador. Normalmente escribo un ciclo de temporizador como este:

  void TimeLoop(object arg) { stopTimer(); //Do some stuff startTimer(); } 

También puede lock(...) su ciclo principal para proteger contra la reentrada.

las excepciones no controladas en los temporizadores se tragan y matan silenciosamente el temporizador

envuelve el cuerpo de tu código de temporizador en un bloque try-catch

Lo he visto antes con temporizador y servicios en bucle. Por lo general, el caso es que se detecta una excepción que detiene el temporizador o la secuencia de bucles, pero no la reinicia como parte de la recuperación de excepciones.

Para sus otros puntos … No creo que haya nada “elegante” en el temporizador. Para mí, es más sencillo ver una operación de bucle en el código que los métodos del temporizador. Pero la elegancia es subjetiva.

¿Problema de memoria? No si lo escribes apropiadamente. Tal vez una carga del procesador si su Thread.Sleep () no está configurado correctamente.

http://support.microsoft.com/kb/842793

Este es un error conocido que ha resurgido en el Framework más de una vez.

La solución más conocida: no use temporizadores. He hecho que este error sea ineficaz haciendo un tonto loop “while (true)”.

Su kilometraje puede variar, así que verifique con su combinación de bits de OS / Framework.

Tema interesante. Si realmente está relacionado con el tiempo (es decir, no es una excepción), entonces me pregunto si puede reciclar periódicamente el temporizador, es decir,

 private void tickTack_Elapsed(object sender, ElapsedEventArgs e) { CheckForRecycle(); // ... actual code } private void CheckForRecycle() { lock(someLock) { if(++tickCount > MAX_TICKS) { tickCount = 0; tickTack.Stop(); // re-create timer tickTack = new Timer(...); tickTack.Elapsed += ... tickTack.Start(); } } } 

Probablemente OnStart unir fragmentos de esto con OnStart / OnStop etc. para reducir la duplicación.

¿Has revisado los registros de errores? Tal vez se quede sin temporizadores de alguna manera. Tal vez pueda crear solo un temporizador cuando inicialice el ArchiveService y saltee las cosas de OnStart.

He hecho exactamente lo mismo que usted en algunos proyectos, pero no he tenido el problema.

¿Tiene código en el tickTac_Elapsed que puede estar causando esto? ¿Como un bucle que nunca termina o algún error que detiene el temporizador, usando hilos y esperando el final de esos y así sucesivamente?