Este team de expertos luego de algunos días de trabajo y recopilar de datos, obtuvimos la respuesta, deseamos que todo este artículo sea de gran utilidad para tu proyecto.
Solución:
Este no es el uso correcto de System.Threading.Timer. Cuando crea una instancia del temporizador, casi siempre debe hacer lo siguiente:
_timer = new Timer( Callback, null, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
Esto le indicará al temporizador que marque solo una vez cuando haya transcurrido el intervalo. Luego, en su función de devolución de llamada, cambie el temporizador una vez que el trabajo se haya completado, no antes. Ejemplo:
private void Callback( Object state )
// Long running operation
_timer.Change( TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite );
Por lo tanto, no hay necesidad de mecanismos de bloqueo porque no hay concurrencia. El temporizador activará la siguiente devolución de llamada después de que haya transcurrido el siguiente intervalo + el tiempo de la operación de ejecución prolongada.
Si necesita ejecutar su temporizador exactamente en N milisegundos, le sugiero que mida el tiempo de la operación de ejecución prolongada con el cronómetro y luego llame al método Cambiar de manera adecuada:
private void Callback( Object state )
Stopwatch watch = new Stopwatch();
watch.Start();
// Long running operation
_timer.Change( Math.Max( 0, TIME_INTERVAL_IN_MILLISECONDS - watch.ElapsedMilliseconds ), Timeout.Infinite );
I fuertemente anime a cualquiera que esté usando .NET y esté usando CLR que no haya leído el libro de Jeffrey Richter – CLR a través de C#, para leer es lo antes posible. Los temporizadores y los grupos de subprocesos se explican con gran detalle allí.
No es necesario detener el temporizador, vea una buena solución en esta publicación:
“Podría dejar que el temporizador continúe activando el método de devolución de llamada, pero envuelva su código no reentrante en un Monitor.TryEnter/Exit. No es necesario detener/reiniciar el temporizador en ese caso; las llamadas superpuestas no adquirirán el bloqueo y regresarán de inmediato”.
private void CreatorLoop(object state)
if (Monitor.TryEnter(lockObject))
try
// Work here
finally
Monitor.Exit(lockObject);
Esta usando System.Threading.Timer
¿obligatorio?
Que no, System.Timers.Timer
tiene a mano Start()
y Stop()
métodos (y un AutoReset
propiedad que puede establecer falsede manera que la Stop()
no es necesario y simplemente llamas Start()
después de ejecutar).
Más adelante puedes encontrar las ilustraciones de otros sys admins, tú también eres capaz dejar el tuyo si dominas el tema.