Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is System.Threading.Timer efficient enough for thousands of concurrent timers?

I'm working on a request timeout mechanism. 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)

like image 949
Jeff Cyr Avatar asked Mar 03 '10 21:03

Jeff Cyr


2 Answers

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.

like image 157
Aaronaught Avatar answered Oct 27 '22 01:10

Aaronaught


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.

like image 36
Wiseheathen Avatar answered Oct 26 '22 23:10

Wiseheathen