tags:

views:

757

answers:

3

For some odd reason the Elapsed event is firing twice, where it should definitely be firing once. And immediately after, the timer ceases to work... The code structure is somewhat like this: A certain object is defined to fire a certain event when a value it contains, which is constantly updated in 500-1500ms intervals, increases in over X sum compared to the previous value.

For example, if I define my X as 2, and the values I'm receiving are 1,2,1,2,3,4,8 for example, the event will fire when 8 is entered. The event handler for that event starts the aforementioned timer, which runs for Y time before it elapses and fires the problematic event. If the value returns to normal before the timer elapses, the timer is reset.

So, the overall result should be an application that measures a certain dynamic value, and monitors it for large X size exceptions that occur for over Y seconds time.

The overall result in code looks something like

vMonitor.Range=X;
vMonitor.Over+= new EventHandler(StartTimer);
vMonitor.Normal+= new EventHandler(StopTimer);
vTimer.Elapsed+= new EventHandler(RaiseAlert);
source.BeginUpdate(vMonitor.Value);

The actual problem is that the RaiseAlert is fired twice upon the timers elapsing, and then its as if the Timer stops working completely, not firing at all anymore. I think its worth mentioning that the full application contains a lot of thread activity, with atleast 2 threads running at a time, updating the vMonitor values.

Any Thoughts?

Update:

About the thread matter, its fairly complex to explain the exact structure, but I can say that the vMonitor object is contained in another object, that contains the updating value, which is constantly changed by the various threads, in a monitored manner, of course. Whenever the parent object's value is updated, its compared to vMonitor, and the proper event is fired. The value in vMonitor is subsequently replaced by the parent objects value.

EDIT: I've just verified it again, the vTimer.Elapsed delegate holds only one, correct, event handler.

A: 

Well my most basic instinct would be that somehow you actually have two event wireups to the Elapsed event - resulting in two events firing. I've been caught out through this, sometimes because I've added the event wireup manually when it has already been added in the designer, or there is some inheritance aspect here where the wireup is already in a base class and you are repeating it in a derived class.

Of course if there are multiple threads then that is a whole different ball game!

Calanus
A: 

Edit to take into account what Mitch had said because I completely forgot that's the easiest answer. In the method that handles the Elapsed event make sure you are first stopping your timer so that the event will not fire again while it is being handled.

slude
+2  A: 

From MSDN:

The Elapsed event is raised on a ThreadPool thread. If processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. Thus, the event handler should be reentrant.

Mitch Wheat