views:

278

answers:

4

I'm working on a request timeout mecanism. My initial approach would be to create one System.Threading.Timer for each request. The number of concurrent requests could scale up to thousands.

I'm wondering if I should instead create a TimeoutScheduler that would internally use only one timer instead of having one per request.

Can anyone who knows the internals of System.Threading.Timer give me some insights on if a TimeoutScheduler would be a good idea or if it would only try to optimize something already efficient enough.

Note: For my scenario, the timer precision is not important.

(I did some performance test with System.Threading.Timer with alot of concurrent timers. It seemed to scale well, but I'm not sure if it will put unwanted pressure in a real system)

+6  A: 

I will direct you to this post from Raymond Chen:

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

Technically there is no problem with creating thousands of them. Just be aware that these use global system resources, so you will eventually hit an upper limit and/or start starving other programs (including Windows itself) if you go crazy with it.

Also make sure you dispose the timers when you're done with them, otherwise you'll end up with a huge resource leak.


I do have to say, this sounds like something you could implement with a single timer; just maintain a dictionary of active requests and timeouts, and on each tick, go through the whole dictionary and check each entry. You could improve performance by making it a sorted list; that way if nothing is timing out for another 5 minutes, the tick method will exit after looking at the first entry.

In addition to the above, you could also dynamically adjust the tick interval to fire whenever the next request is scheduled to time out; then on each tick, reschedule the next tick to the next timeout. This would take up virtually no system resources (just one timer) and also be very fast (as with your one-timer-per-request idea, you would only be running expensive code when requests actually expire).

Even though you can create thousands of timers, the above approach will scale far better and will also be a lot easier to test and maintain.

Aaronaught
Raymond Chen's article describes a different kind of timer.
SLaks
@SLaks: Raymond Chen's article doesn't describe any specific kind of timer. He makes a passing mention to the Windows Forms timer at the end, and I assure you that I'm well aware of the difference, but **all** .NET timers wrap Windows timers and are all subject to the same caveats.
Aaronaught
@Aaronaught: Actually, Raymond Chen's article describes timers created by SetTimer. The `System.Threading.Timer` is actually a Timer Queue Timer (http://msdn.microsoft.com/en-us/library/ms686796(v=VS.85).aspx), which is essentially a single timer and an efficient mechanism of determining when to fire the next event.
Jim Mischel
+1  A: 

A timeout scheduler is a good idea, but Timers are the lowest priority execution. If this is for scheduling timeout your most reliable option is going to be a thread that tracks the timeouts of other threads and the updates with QueryPerormanceCounter and QueryPerformanceFrequency. These will be blocking class, but inside of their own thread it will not matter. You might also consider making the timeout scheduler run at a higher priority.

Wiseheathen
A: 

Sounds like a job for quartz.net.

kenny
+1  A: 

System.Threading.Timer executes it's TimerCallback on a ThreadPool, creating 1000's would possibly lead to threadpool starvation.

MSDN System.Threating.Timer

Use a TimerCallback delegate to specify the method you want the Timer to execute. The timer delegate is specified when the timer is constructed, and cannot be changed. The method does not execute on the thread that created the timer; it executes on a ThreadPool thread supplied by the system.

The System.Timers.Timer behaves in the same way. A TimeoutScheduler is the way to go.

ParmesanCodice