How do I efficently use timers
I have some Objects that Expire after a certain amount of time. Right now I am using a Single timer to raise an event every 10 seconds and run thru the object collection and see开发者_如何转开发 if anything has expired.
Instead of this I am considering adding a timer to each object and setting it to fire an event to expire at the desired time.
I think the most appropriate timer is the System.Timers.Timer
Does any one have any thoughts on this?
I have a test rig so I will be able to compare what I have now and the refactored implementation but I would like to think this is a good idea before I start.
I wouldn't create that many timers, because of the overhead it would be.
Perhaps it's better to have one timer. Now this timer shouldn't trigger every 10 seconds, it should trigger when the next element expires. so you have some kind of "just in time trigger"
If you have 200 elements and the first will expire in 2 seconds, you could have a timer of 2 seconds regardless that the last element will expire in 2 years or so...
I do prefer System.Threading.Timer
over the one you mentioned. The reason is that System.Timers.Timer
will consume all unhandled exceptions and therefore hide errors in your application.
I would also make a list of objects and traverse it in the timer method. It's a sound approach and not very hard to implement (Keep It Simple and Stupid)
The only reason to not do so is if it's important that the objects are check after exactly 10 seconds (and not 11 or 12 seconds). It all depends on how long each execution takes.
As I assume the objects can't really "self destruct" when expired, I would go with the single static Timer checking what objects have expired, and Dispose them before removing from the collection.
The System.Timers.Timer
is good for this task, just make sure to wrap everything with try..catch
because single uncaught error will cause the timer to stop ticking and you won't even get any notification for this.
Do you have a list of objects with set expiry times?
e.g. obj1, expires at 12:35:01 obj2, expires at 12:37:14 obj3, expires at 12:38:56 obj4, expires at 12:43:44
If we know the expiry times when the collection is created we can use a single timer and a list of intervals to trigger the timer when the objects need to be removed
e.g.
Wait time in seconds To Be Removed
int1 12:35:01 - now() obj1
int2 12:37:14 - 12:35:01 obj2
int3 12:38:56 - 12:37:14 obj3
int4 12:43:44 - 12:38:56 obj4
A) Peek the first entry in the 'delta list' (I have heard it called this before but could not give you a citation) and set the timer interval to the wait time.
B) When the timer tiggers, remove the first entry from the delta list and do whatever needs to be done with the object from the source collection.
Back to A
When an item is added to the collection you need to add a new entry to the delta list in the correct position. Not overly complicated but allow for the timer popping while you are in the middle of adding.
Pros: Only one timer. It's all you need. A timer per object is going to suck up a lot of resources.
You only need to check through your whole collection at startup and then partial scans whenever new items are added.
Never miss an expiry. It may not be important but a fixed time check means that we are late on removing some items.
Cons: More complicated to implement than simply scanning the whole collection on a timer pop.
Before changing anything, is the current implementation causing any problems?
You will get a performance bump from the timer popping only when needed and from not having to scan the list each time. Are we talking 100 entries or 100,000? Would the performance bump be noticeable?
You will no longer have any 'late' expiries (being removed from the list after their time out). Does this matter?
hth, Alan
精彩评论