visual tiempo threading studio net ejecucion c# multithreading timer

c# - tiempo - vb threading timer



¿Los cronómetros C#transcurren en un hilo separado? (5)

Cada evento transcurrido se activará en el mismo subproceso a menos que todavía se esté ejecutando un Elapsed previo.

Por lo tanto, maneja la colisión para usted

intenta poner esto en una consola

static void Main(string[] args) { Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); var timer = new Timer(1000); timer.Elapsed += timer_Elapsed; timer.Start(); Console.ReadLine(); } static void timer_Elapsed(object sender, ElapsedEventArgs e) { Thread.Sleep(2000); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); }

obtendrás algo como esto

10 6 12 6 12

donde 10 es el hilo que llama y 6 y 12 están disparando desde el evento transcurrido bg. Si elimina el Thread.Sleep (2000); obtendrás algo como esto

10 6 6 6 6

Como no hay colisiones

Pero esto todavía te deja con un problema. si está activando el evento cada 5 segundos y tarda 10 segundos en editarlo, necesita un bloqueo para omitir algunas ediciones.

¿Transmite un System.Timers.Timer un hilo separado del hilo que lo creó?

Digamos que tengo una clase con un temporizador que se dispara cada 5 segundos. Cuando el temporizador se dispara, en el método transcurrido, se modifica algún objeto. Digamos que lleva mucho tiempo modificar este objeto, como 10 segundos. ¿Es posible que me encuentre con colisiones de hilos en este escenario?


Para System.Timers.Timer, en una secuencia separada, si SynchronizingObject no está configurado.

static System.Timers.Timer DummyTimer = null; static void Main(string[] args) { try { Console.WriteLine("Main Thread Id: " + System.Threading.Thread.CurrentThread.ManagedThreadId); DummyTimer = new System.Timers.Timer(1000 * 5); // 5 sec interval DummyTimer.Enabled = true; DummyTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnDummyTimerFired); DummyTimer.AutoReset = true; DummyTimer.Start(); Console.WriteLine("Hit any key to exit"); Console.ReadLine(); } catch (Exception Ex) { Console.WriteLine(Ex.Message); } return; } static void OnDummyTimerFired(object Sender, System.Timers.ElapsedEventArgs e) { Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId); return; }

Salida que vería si DummyTimer disparara en un intervalo de 5 segundos:

Main Thread Id: 9 12 12 12 12 12 ...

Entonces, como se ve, OnDummyTimerFired se ejecuta en el hilo Trabajadores.

No, más complicaciones: si reduce el intervalo para decir 10 ms,

Main Thread Id: 9 11 13 12 22 17 ...

Esto se debe a que si la ejecución previa de OnDummyTimerFired no se realiza cuando se activa el siguiente tic, entonces .NET creará un nuevo hilo para hacer este trabajo.

Para complicar aún más las cosas, "la clase System.Timers.Timer proporciona una manera fácil de lidiar con este dilema: expone una propiedad Public SynchronizingObject. Establecer esta propiedad en una instancia de Windows Form (o un control en Windows Form) asegurará que el código en su controlador de eventos de Elapsed se ejecuta en el mismo hilo en el que SynchronizingObject fue instanciado ".

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx#S2


Si el evento transcurrido toma más tiempo que el intervalo, creará otro hilo para elevar el evento transcurrido. Pero hay una solución para esto

static void timer_Elapsed(object sender, ElapsedEventArgs e) { try { timer.Stop(); Thread.Sleep(2000); Debug.WriteLine(Thread.CurrentThread.ManagedThreadId); } finally { timer.Start(); } }



Depende. El System.Timers.Timer tiene dos modos de operación.

Si SynchronizingObject se establece en una instancia de ISynchronizeInvoke , el evento de ISynchronizeInvoke se ejecutará en el hilo que aloja el objeto de sincronización. Por lo general, estas instancias de ISynchronizeInvoke no son más que simples instancias antiguas de Control y Form que todos estamos familiarizados. Entonces, en ese caso, el evento Elapsed se invoca en el subproceso de la interfaz de usuario y se comporta de manera similar al System.Windows.Forms.Timer . De lo contrario, realmente depende de la instancia específica de ISynchronizeInvoke que se usó.

Si SynchronizingObject es nulo, el evento Elapsed se invoca en un subproceso de ThreadPool y se comporta de forma similar al System.Threading.Timer . De hecho, en realidad usa un System.Threading.Timer detrás de las escenas y realiza la operación de cálculo de referencias después de que recibe la devolución de llamada del temporizador si es necesario.