2010-03-03 17 views
5

Estoy trabajando en un mecanismo de tiempo de espera de solicitud. Mi enfoque inicial sería crear un System.Threading.Timer para cada solicitud. El número de solicitudes simultáneas podría escalar hasta miles.¿System.Threading.Timer es lo suficientemente eficiente para miles de temporizadores simultáneos?

Me pregunto si debería crear un TimeoutScheduler que internamente usaría solo un temporizador en lugar de tener uno por solicitud.

¿Alguien que conozca las partes internas de System.Threading.Timer me da algunas ideas sobre si un TimeoutScheduler sería una buena idea o si solo trataría de optimizar algo que ya es lo suficientemente eficiente?

Nota: Para mi escenario, la precisión del temporizador no es importante.

(he hecho un poco de prueba de rendimiento con System.Threading.Timer con un montón de temporizadores simultáneos. Parecía escalar bien, pero no estoy seguro de si se va a poner presión no deseada en un sistema real)

Respuesta

11

I le dirigirá a este post de Raymond Chen:

What is the maximum number of timers a program can create?

Técnicamente no hay ningún problema con la creación de miles de ellos. Solo tenga en cuenta que estos utilizan recursos del sistema global, por lo que eventualmente alcanzará un límite superior y/o empezará a pasar hambre con otros programas (incluido el propio Windows) si se vuelve loco con él.

También asegúrese de disponer de los temporizadores cuando haya terminado con ellos, de lo contrario terminará con una gran pérdida de recursos.


Tengo que decir que esto suena como algo que podría implementar con un solo temporizador; solo mantenga un diccionario de solicitudes activas y tiempos de espera, y en cada tilde, revise todo el diccionario y verifique cada entrada. Puede mejorar el rendimiento convirtiéndolo en una lista ordenada; De esa manera, si nada se agota durante otros 5 minutos, el método de tic saldrá después de mirar la primera entrada.

Además de lo anterior, también puede ajustar dinámicamente el intervalo de marcación para disparar siempre que se programe el tiempo de espera de la siguiente solicitud; luego en cada tilde, reprogramar el siguiente tic hasta el próximo tiempo de espera. Esto prácticamente no requeriría recursos del sistema (solo un temporizador) y también sería muy rápido (como con su idea de un solo temporizador por solicitud, solo estaría ejecutando un código costoso cuando las solicitudes realmente expiren).

Aunque puede crear miles de temporizadores, el enfoque anterior escalará mucho mejor y también será mucho más fácil de probar y mantener.

+0

El artículo de Raymond Chen describe un tipo diferente de temporizador. – SLaks

+0

@SLaks: el artículo de Raymond Chen no describe ningún tipo específico de temporizador. Hace una mención de paso al temporizador de Windows Forms al final, y le aseguro que soy consciente de la diferencia, pero ** todos los temporizadores de ** .NET envuelven los temporizadores de Windows y están sujetos a las mismas advertencias. – Aaronaught

+1

En realidad, el artículo de Raymond Chen describe temporizadores creados por SetTimer. El 'System.Threading.Timer' es en realidad un Timer Queue Timer (http://msdn.microsoft.com/en-us/library/ms686796(v=VS.85).aspx), que es esencialmente un solo temporizador y un mecanismo eficiente para determinar cuándo disparar el próximo evento. –

1

Un programador de tiempo de espera es una buena idea, pero los temporizadores son la ejecución de menor prioridad. Si esto es para programar el tiempo de espera, su opción más confiable será un hilo que rastrea los tiempos de espera de otros hilos y las actualizaciones con QueryPerormanceCounter y QueryPerformanceFrequency. Estos bloquearán la clase, pero dentro de su propio hilo no importará. También podría considerar hacer que el programador de tiempo de espera se ejecute con una prioridad más alta.

1

System.Threading.Timer ejecuta su TimerCallback en un ThreadPool, la creación de 1000 posiblemente lleve a la inanición de threadpool.

MSDN System.Threating.Timer

Utilice un delegado TimerCallback para especificar el método que desea que el temporizador a ejecutar. El temporizador delegado se especifica cuando se construye el temporizador y no se puede cambiar. El método no se ejecuta en el hilo que creó el temporizador; se ejecuta en un subproceso de ThreadPool proporcionado por el sistema.

El temporizador System.Timers.Timer se comporta de la misma manera. Un TimeoutScheduler es el camino a seguir.

Cuestiones relacionadas