Pregunta

Estoy escribiendo una aplicación que necesitará utilizar Timers, pero potencialmente muchos de ellos.¿Qué tan escalable es el System.Threading.Timer ¿clase?La documentación simplemente dice que es "liviana", pero no explica más.¿Estos temporizadores son absorbidos por un solo subproceso (o un grupo de subprocesos muy pequeño) que procesa todas las devoluciones de llamada en nombre de un Timer, o cada uno Timer tiene su propio hilo?

Supongo que otra forma de reformular la pregunta es:Cómo es System.Threading.Timer ¿implementado?

¿Fue útil?

Solución

Digo esto en respuesta a muchas preguntas:No olvide que el código fuente (administrado) del marco está disponible.Puede utilizar 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 puedes verlo...

Sin embargo, definitivamente usan subprocesos de grupo en lugar de subprocesos por temporizador.

La forma estándar de implementar una gran colección de temporizadores (que es como lo hace el kernel internamente, y sospecho que es indirectamente cómo termina su gran colección de temporizadores) es mantener la lista ordenada por tiempo hasta el vencimiento, de modo que la El sistema sólo tiene que preocuparse por comprobar el siguiente temporizador que va a expirar, no toda la lista.

Aproximadamente, esto da O(log n) para iniciar un temporizador y O(1) para procesar temporizadores en ejecución.

Editar:Acabo de mirar el libro de Jeff Richter.Él dice (de Threading.Timer) que usa un solo hilo para todos los objetos Timer, este hilo sabe cuándo funcionará el próximo temporizador (es decir,como arriba) vence y llama a ThreadPool.QueueUserWorkItem para las devoluciones de llamada según corresponda.Esto tiene el efecto de que si no termina de atender una devolución de llamada en un temporizador antes de que venza la siguiente, su devolución de llamada volverá a ingresar en otro subproceso del grupo.Entonces, en resumen, dudo que vea un gran problema al tener muchos temporizadores, pero podría sufrir un agotamiento del grupo de subprocesos si una gran cantidad de ellos se activan al mismo tiempo y/o sus devoluciones de llamada se ejecutan lentamente.

Otros consejos

Creo que es posible que desee repensar su diseño (es decir, si usted mismo tiene control sobre el diseño).Si está utilizando tantos temporizadores que esto realmente le preocupa, es evidente que existe cierto potencial de consolidación allí.

Aquí hay un buen artículo de MSDN Magazine de hace unos años que compara las tres clases de temporizadores disponibles y brinda una idea de sus implementaciones:

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

Consolidarlos.Cree un servicio de temporizador y solicite los temporizadores.Solo necesitará mantener 1 temporizador activo (para la siguiente llamada debido) ...

Para que esto sea una mejora con respecto a la simple creación de muchos objetos Threading.Timer, debe asumir 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 las partes nativas del marco, por lo que es posible que tenga razón).

^^ como dice DannySmurf:Consolidarlos.Cree un servicio de temporizador y solicítelo para los temporizadores.Solo necesitará mantener 1 temporizador activo (para la próxima llamada) y un historial de todas las solicitudes de temporizador y recalcularlo en AddTimer()/RemoveTimer().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top