2010-09-03 11 views
17

Tengo una aplicación de servicio de Windows. Y depurándolo ejecutando en modo consola.System.Threading.Timer no se activa después de algún tiempo

Aquí http://support.microsoft.com/kb/842793 está escrito que Timers.Timer tiene un error y no se activa en los servicios de Windows. Y la solución consiste en utilizar Threading.Timer Y este artículo es para .NET 1.0 y 1.1

Estoy usando .NET 4 pero después de un tiempo Threading.Timer también no se dispara. Entonces, ¿cuál puede ser el motivo de esto? ¿Y qué puede sugerir como una solución?

Gracias,

Saludos cordiales

EDIT: He cambiado temporizador de Threading.Timer a Timers.Timer y está funcionando sin ningún problema.

+1

Creo que una buena forma de acelerar la solución de este problema es publicar la inicialización del temporizador y el código de inicio. – Vokinneberg

+0

¿Usa algún código no administrado? –

+0

Llamo a una función desde el win32 dll nativo, pero está en otro hilo – AFgone

Respuesta

47

¿Está manteniendo una referencia a su temporizador en algún lugar para evitar que se recolecte basura?

De the docs:

Mientras usted está utilizando un temporizador, que que tener una referencia a él. Al igual que con cualquier objeto administrado, un temporizador está sujeto a la recolección de basura cuando hay sin referencias. El hecho de que un temporizador todavía esté activo no impide que se recopile .

+0

sí, existe una referencia a un temporizador – AFgone

+2

@AFgone: ¿En dónde? ¿Cuán * seguro * eres tú de que no se está recogiendo basura? –

+2

+1 - Te amo Jon Skeet, esto me estaba volviendo loco :) – Tr1stan

4

¿Funciona?

Personalmente, sugiero utilizar una función RegisterWaitForSingleObject en contraposición a los temporizadores por la razón exacta está ejecutando en. RegisterWaitForSingleObject registra un delegado al que se llama en el intervalo que establece de manera análoga a un temporizador y es super fácil de implementar. Podría tener un arnés de prueba funcionando en cuestión de horas. Utilizo este método de activación de intervalo en mis Servicios de Windows y es una solución estable comprobada que funciona para mí.

Lea el siguiente enlace y vaya a los enlaces dentro del artículo para ejemplos de código y tutoriales.

Ejecución de un proceso periódico en .NET utilizando un servicio de Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

4

Su objeto de temporizador se sale del ámbito y se borra por el recolector de basura después de algún tiempo, que para las devoluciones de llamada de disparo.

Guarde la referencia en un miembro de la clase.

0

Ejemplo completo de un servicio de Windows que utiliza la biblioteca empresarial para el registro y los hilos recurrentes. Eliminar las líneas logger.write si no está utilizando la biblioteca empresarial

namespace Example.Name.Space 
{ 
public partial class SmsServices : ServiceBase 
{ 
    private static String _state = "";   
    private ManualResetEvent _stop = new ManualResetEvent(false); 
    private static RegisteredWaitHandle _registeredWait; 
    public WindowsServices() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    {       
     Logger.Write("Starting service", LoggerCategory.Information);    
     _stop.Reset(); 
     _registeredWait = ThreadPool.RegisterWaitForSingleObject(_stop, 
      PeriodicProcess, null, 5000, false); 

    } 

    protected override void OnStop() 
    {    
     // UpdateTimer.Stop(); 
     _stop.Set(); 
     Logger.Write("Stopping service", LoggerCategory.Information); 
    }   
    private static void PeriodicProcess(object state, bool timedOut) 
    { 

     if (timedOut) 
     { 
      // Periodic processing here 
      Logger.Write("Asserting thread state", LoggerCategory.Debug); 
      lock (_state) 
      { 
       if (_state.Equals("RUNNING")) 
       { 
        Logger.Write("Thread already running", LoggerCategory.Debug); 
        return; 
       } 
       Logger.Write("Starting thread", LoggerCategory.Debug); 
       _state = "RUNNING"; 
      } 
      Logger.Write("Processing all messages", LoggerCategory.Information); 
      //Do something 
      lock (_state) 
      { 
       Logger.Write("Stopping thread", LoggerCategory.Debug); 
       _state = "STOPPED"; 
      } 
     } 
     else 
      // Stop any more events coming along 
      _registeredWait.Unregister(null); 


    } 
    } 
} 
Cuestiones relacionadas