System.Timers.Timer The elapsed event that is executed after the timer.Stop () call

Background: I have a timer that I use to track how much time has passed since the serialPort DataReceived event was fired. I create my own solution for this instead of using the built-in timeout event, because I get a continuous stream of data, instead of sending a request and receiving a single response.

Problem: In the DataReceived handler, I have an instruction to stop the timer so that it does not pass. the problem is that it repeatedly terminates the expired handler handler.

I read that you can use SynchronizingObject to solve this problem, but I'm not sure how to do it.

Here is my code: I tried to cut everything that was not considered relevant.

private System.Timers.Timer timeOut; private System.Timers.Timer updateTimer; public void start() { thread1 = new Thread(() => record()); thread1.Start(); } public void requestStop() { this.stop = true; this.WaitEventTest.Set(); } private void record() { timeOut = new System.Timers.Timer(500); //** .5 Sec updateTimer = new System.Timers.Timer(500); //** .5 Sec timeOut.Elapsed += TimeOut_Elapsed; updateTimer.Elapsed += updateTimer_Elapsed; updateTimer.AutoReset = true; comport.Open(); comport.DiscardInBuffer(); comport.Write(COMMAND_CONTINUOUSMODE + "\r"); stopwatch.Reset(); stopwatch.Start(); recordingStartTrigger(); //** Fire Recording Started Event timeOut.Start(); updateTimer.Start(); this.waitHandleTest.WaitOne(); //** wait for test to end timeOut.Stop(); updateTimer.Stop(); comport.Write(COMMAND_COMMANDMODE + Environment.NewLine); comport.DiscardInBuffer(); comport.Close(); recordingStopTrigger(status); //** Fire Recording Stopped Event stopwatch.Stop(); } //*********************************************************************************** //** Events Handlers private void comDataReceived_Handler(object sender, SerialDataReceivedEventArgs e) { double force = -100000; string temp = "-100000"; //timeOut.SynchronizingObject.Invoke(new Action(()=> {timeOut.Stop();}), new object[] {sender, e}); timeOut.Stop(); //** I removed my action code here, keep things simple. timeOut.Start(); } private void TimeOut_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { timeOut.Stop(); updateTimer.Stop(); //** fire delegate that GUI will be listening to, to update graph. if (eventComTimeOut != null && this.stop == false) { if (eventComTimeOut(this, new eventArgsComTimeOut(comport.PortName, "READ"))) { //retry = true; comport.Write(COMMAND_CONTINUOUSMODE + "\r"); updateTimer.Start(); timeOut.Start(); } else { this.stop = true; //retry = false; this.WaitEventTest.Set(); status = eventArgsStopped.Status.failed; } } } void updateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { //** fire delegate that GUI will be listening to, to update graph. List<Reading> temp = new List<Reading>(report.Readings_Force); eventNewData(this, new eventArgsNewData(temp)); } 
+7
c # timer
source share
2 answers

This is a well-known behavior. System.Timers.Timer internally uses ThreadPool to execute. Runtime will queue Timer in threadpool. It would already put before you called the Stop method. It will fire in the past tense.

To avoid this, set Timer.AutoReset to false and start the timer in the expired handler if you need one. Setting AutoReset false causes the timer to start only once, so to start the timer again at a manual interval, start the timer.

 yourTimer.AutoReset = false; private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { try { // add your logic here } finally { yourTimer.Enabled = true;// or yourTimer.Start(); } } 
+24
source share

I paused in the timer with this code. it works for me.

 Private cTimer As New System.Timers.Timer Private Sub inittimer() cTimer.AutoReset = True cTimer.Interval = 1000 AddHandler cTimer.Elapsed, AddressOf cTimerTick cTimer.Enabled = True End Sub Private Sub cTimerTick() If cTimer.AutoReset = True Then 'do your code if not paused by autoreset false End If End Sub 
+2
source share

All Articles