2011-10-25 17 views
16

Estoy tratando de entender cuando el System.Timers.Timer aumenta el evento transcurrido, ¿se plantea en un hilo independiente?Hacer System.Timers.Timer ejecutar en Hilos independientes?

Mi ejemplo de abajo parece sugerir que los tres temporizadores ejecutan de forma independiente en sus propios hilos:

class Program 
{ 
    static System.Timers.Timer timer = new System.Timers.Timer(); 
    static System.Timers.Timer timer2 = new System.Timers.Timer(); 
    static System.Timers.Timer timer3 = new System.Timers.Timer(); 

    static void Main(string[] args) 
    { 
     timer.Elapsed += new System.Timers.ElapsedEventHandler(
      timer_Elapsed); 
     timer2.Elapsed += new System.Timers.ElapsedEventHandler(
      timer2_Elapsed); 
     timer3.Elapsed += new System.Timers.ElapsedEventHandler(
      timer3_Elapsed); 

     timer.Interval = 1000; 
     timer2.Interval = 1000; 
     timer3.Interval = 1000; 

     timer.Start(); 
     timer2.Start(); 
     timer3.Start(); 

     Console.WriteLine("Press \'q\' to quit the sample."); 
     while (Console.Read() != 'q') ; 
    } 

    static void timer3_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     timer3.Stop(); 
     Console.WriteLine("Timer 3 Hit...");    
     timer3.Start(); 
    } 

    static void timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     timer2.Stop(); 
     Console.WriteLine("Timer 2 Hit..."); 
     Thread.Sleep(2000); 
     timer2.Start(); 
    } 

    static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     timer.Stop(); 
     Console.WriteLine("Timer 1 Hit..."); 
     Thread.Sleep(10000); 
     timer.Start(); 
    } 
} 

enter image description here

+1

Sí, los temporizadores están roscados. – qJake

+0

Sí, se ejecutan en un hilo diferente. –

Respuesta

20

Según el MSDN, en System.Timers.Timer cuando el evento Elapsed incendios que se llama en un hilo en el sistema de hilos-piscina:

Si la propiedad SynchronizingObject es nada, el evento transcurrido se eleva en un ThreadPool hilo. Si el procesamiento del evento transcurrido dura más que el intervalo, el evento puede volver a plantearse en otro hilo de ThreadPool. En esta situación, el controlador de eventos debe ser reentrante.

Dado que el valor predeterminado de SynchronizingObject es nulo, todos los eventos transcurridos se manejarán en el grupo de subprocesos. Por lo tanto, depende de qué tan completo esté el grupo de subprocesos, si hay subprocesos libres, entonces cada evento transcurrido probablemente se ejecute al mismo tiempo en subprocesos independientes. Si por alguna razón, sin embargo, el grupo de subprocesos del sistema ya está en uso, es posible que los eventos transcurridos se serialicen a medida que se programan.

El punto principal es: "depende". Es decir, se les permitirá ejecutar en paralelo siempre que haya subprocesos libres en el grupo.

Referencia: MSDN on System.Timers.Timer

+0

Todas las respuestas fueron correctas, sin embargo, creo que ThreadPool es el componente clave aquí. – newbie

4

en base a su código que debe ser, ya que Thread.Sleep es una llamada de bloqueo. Ninguno de los otros temporizadores dispararía si se ejecutaran en el mismo hilo.

Puede sacar System.Threading.Thread.CurrentThread.ManagedThreadId en cada uno para estar seguro.

2

Sí, cada vez transcurrido se llama, la devolución de llamada se dispara en su propio hilo.

Además, no hay nada que impida que un controlador de eventos transcurrido se active antes de que se complete el anterior. Por ejemplo, si su temporizador se dispara cada 500 milisegundos, pero el código del controlador de eventos transcurrido tarda 2 segundos en completarse, el código transcurrido puede acceder a los mismos recursos (objetos que no son seguros para subprocesos, archivos, etc.).

4

Es bastante complejo. El documentation dice lo siguiente:

El temporizador está diseñado para su uso con los subprocesos de trabajo en un entorno multiproceso basado en servidor. Los temporizadores de servidor pueden moverse entre subprocesos para manejar el evento Elapsed elevado, lo que da como resultado más precisión que los temporizadores de Windows al elevar el evento a tiempo.

y luego esto:

Si la propiedad SynchronizingObject es nulo, el evento transcurrido se eleva en un hilo ThreadPool. Si el procesamiento del evento transcurrido dura más que el intervalo, el evento puede volver a plantearse en otro hilo de ThreadPool. En esta situación, el controlador de eventos debe ser reentrante.

y luego esto:

Si utiliza el temporizador con un elemento de la interfaz de usuario, como un formulario o control, sin colocar el temporizador en ese elemento de la interfaz de usuario, asignar el formulario o control que contiene el temporizador a la propiedad SynchronizingObject, de modo que el evento se clasifique en el hilo de la interfaz del usuario.

Por lo tanto, no hay una respuesta simple a su pregunta "¿se trata de un tema independiente?" Depende de muchas cosas.

Cuestiones relacionadas