c# - timers - ¿Qué tan escalable es System.Threading.Timer?
timers timer vb net (4)
Consolídelos. Crea un servicio de temporizador y pregúntale por los temporizadores. Solo necesitará mantener 1 temporizador activo (para la próxima llamada) ...
Para que esto sea una mejora sobre la simple creación de muchos objetos Threading.Timer, debe suponer que no es exactamente lo que Threading.Timer ya está haciendo internamente. Me interesaría saber cómo llegó a esa conclusión (no he desmontado los elementos nativos del marco, por lo que podría estar en lo cierto).
Estoy escribiendo una aplicación que necesitará hacer uso de Timer
, pero potencialmente muchos de ellos. ¿Qué tan escalable es la clase System.Threading.Timer
? La documentación simplemente dice que es "liviano", pero no explica más. ¿Se atrapan estos temporizadores en un solo hilo (o en un subproceso muy pequeño) que procesa todas las devoluciones de llamada en nombre de un Timer
, o cada Timer
tiene su propio hilo?
Creo que otra forma de reformular la pregunta es: ¿Cómo se implementa System.Threading.Timer
?
Creo que es posible que desee replantearse su diseño (es decir, si usted mismo tiene el control del diseño). Si está utilizando tantos temporizadores que esto es realmente una preocupación para usted, claramente existe cierto potencial de consolidación allí.
Este es un buen artículo de MSDN Magazine de hace unos años que compara las tres clases de temporizador disponibles y brinda una idea de sus implementaciones:
Digo esto en respuesta a muchas preguntas: no olvide que el código fuente (administrado) del marco está disponible. Puede usar esta herramienta para obtenerlo todo: http://www.codeplex.com/NetMassDownloader
Desafortunadamente, en este caso específico, gran parte de la implementación está en código nativo, por lo que no puede verlo ...
Sin embargo, definitivamente usan hilos de grupo en lugar de un hilo por temporizador.
La forma estándar de implementar una gran colección de temporizadores (que es cómo lo hace internamente el kernel, y sospecho que es indirectamente cómo termina su gran colección de temporizadores) es mantener la lista ordenada por tiempo hasta el vencimiento, por lo que el sistema solo tiene que preocuparse de comprobar el próximo temporizador que expirará, no toda la lista.
Aproximadamente, esto da O (log n) para iniciar un temporizador y O (1) para procesar temporizadores en ejecución.
Edición: Acabo de buscar en el libro de Jeff Richter. Él dice (de Threading.Timer) que usa una única secuencia para todos los objetos del temporizador, este subproceso sabe cuándo debe vencer el siguiente temporizador (es decir, como el anterior) y llama a ThreadPool.QueueUserWorkItem para las devoluciones de llamada según corresponda. Esto tiene el efecto de que si no finaliza el mantenimiento de una devolución de llamada en un temporizador antes de que venza la siguiente, su devolución de llamada volverá a ingresar en otra secuencia de grupo. Así que, en resumen, dudo que veas un gran problema con tener muchos temporizadores, pero podrías sufrir el agotamiento de la agrupación de subprocesos si gran cantidad de ellos se activan con el mismo temporizador y / o sus devoluciones se ejecutan lentamente.
^^ como dice DannySmurf: consolídelos. Crea un servicio de temporizador y pregúntale por los temporizadores. Solo necesitará mantener 1 temporizador activo (para la próxima llamada vencida) y un historial de todas las solicitudes de temporizador y recalcular esto en AddTimer () / RemoveTimer ().