2011-05-05 16 views
8

Tengo problemas para crear un temporizador continuo. Hay múltiples hilos escalonados creados en temporizadores que se ejecutarán durante un tiempo y luego se detendrán por completo. Los hilos máximos que estoy permitiendo son 5 y el intervalo del temporizador se establece en 10000. Así que en teoría habría 1 hilo ejecutado cada 2 segundos.System.Threading.Timer no continuo

Esto ocurre por un tiempo, pero luego se detiene. Actualmente estoy probando en una aplicación de consola y escribiendo las respuestas a la aplicación.

No estoy exactamente seguro de lo que está pasando aquí

internal class EngineThreadGenerator 
{ 
    private readonly AutoResetEvent _autoEvent; 
    private readonly Action<string, string> _processQueueDelegate; 
    private readonly Action<string, string> _purgeQueueDelegate; 

    private void createAllowedEmailThreads() 
    { 
     for (int counter = 0; counter < AppSettings.ProcessQueueAllowedThreads; counter++) 
     { 
      EmailThread _emailThread = new EmailThread(_collection, _processQueueDelegate, _purgeQueueDelegate); 
      TimerCallback _timerCallback = _emailThread.InitEmailThread; 
      Timer _stateTimer = new Timer(_timerCallback, _autoEvent, 0, AppSettings.ProcessIntervalInMilliseconds); 

      pauseLoop(); 
     } 
    } 

Cualquier ayuda aquí es muy apreciada! ¡Aclamaciones!

+1

¿Está diciendo que el desove de los hilos se está deteniendo o que los hilos se están deteniendo? ¿Cuánto dura "un tiempo"? –

+0

The Threads themselve, por lo general, se detienen durante 3 minutos. – BoredOfBinary

Respuesta

8

La razón por la cual sus temporizadores están muriendo después de 3 minutos es que tiene mucha memoria disponible.

Lo que significa que el recolector de basura tarda unos 3 minutos en llegar a sus objetos antes de recogerlos.

Se supone que debe mantener una referencia al temporizador durante toda su vida útil. Como no está haciendo eso, el temporizador es elegible para la recolección de basura tan pronto como termine su ciclo.

3 minutos más tarde, o cada vez que GC se acerca, se recopila el temporizador y el código deja de ejecutarse.

Por lo tanto, mantenga una referencia al objeto del temporizador, y debe estar todo listo.

Aquí es un simple script LINQPad probar con:

void Main() 
{ 
    new Timer(Callback, null, 0, 1000); 
    Thread.Sleep(5000); 
    Debug.WriteLine("collecting"); 
    GC.Collect(); 
    GC.WaitForPendingFinalizers(); 
    GC.Collect(); 
    Debug.WriteLine("collected"); 
    Thread.Sleep(5000); 
} 

static void Callback(object state) 
{ 
    Debug.WriteLine("callback"); 
} 

Observe que una vez que el hilo principal corre GC, la devolución de llamada se detiene. Si, por el contrario, se hace una copia del temporizador en un campo:

Timer _Timer; 

void Main() 
{ 
    _Timer = new Timer(Callback, null, 0, 1000); 
    ... 

el temporizador sigue marcando pasado GC.

+0

doh ... mi compilación también está en una aplicación de consola, eso también explicaría por qué no lo haría? – BoredOfBinary

+0

Depende, ¿la aplicación de la consola se queda hasta que se supone que los hilos deben estar listos? Si lo hace, o al menos se supone que debe hacerlo, entonces no hay nada de malo en usar una aplicación de consola para esto, simplemente no dejes que el hilo principal (también conocido como, Program.Main), salga. Cuando lo haga, todas las referencias en China no mantendrán sus temporizadores con vida. –

+0

¡Gracias por su guía! ¿Cómo mantengo ese hilo principal en ejecución? – BoredOfBinary

0

Quizás simplemente no está en este snippit de código, pero ¿alguna vez disminuyó counter?

+0

Wow, ¿un voto a favor? ¿Para qué? El snipit de código original simplemente se repite un par de veces y luego sale, lo que podría explicar por qué funciona durante un tiempo y luego se detiene. – CodingWithSpike

+0

Mis disculpas, pero no te devolví ... – BoredOfBinary

+0

Si lo hice, fue purley por accidente – BoredOfBinary

Cuestiones relacionadas