Hintergrund: Ich habe einen Timer, den ich verwende, um zu verfolgen, wie lange es her ist, seit das serialPort DataReceived-Ereignis ausgelöst wurde. Ich erstelle meine eigene Lösung, anstatt das eingebaute Timeout-Ereignis zu verwenden, da ich einen kontinuierlichen Datenstrom bekomme, anstatt eine Abfrage zu senden und eine Antwort zu erhalten.System.Timers.Timer Abgelaufenes Ereignis, das nach dem Timer ausgeführt wird.Stop() heißt
Das Problem: Im DataReceived-Handler habe ich eine Anweisung, den Timer zu stoppen, so dass es nicht vergehen wird. Das Problem besteht darin, dass das Elapsed-Handler-Nachwort oft noch ausgeführt wird.
Ich habe gelesen, dass es möglich ist, SynchronizingObject verwenden, um dieses Problem zu lösen, aber ich bin mir nicht sicher, wie dies zu erreichen ist.
Hier ist mein Code: Ich habe versucht, alles auszuschneiden, was ich nicht für relevant hielt.
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));
}
@Downvoter Kommentar? –
Was ist der Grund dafür, den Versuch endlich hinzuzufügen? –
@mikejames Im 'try' Block fügen Sie Ihre Logik hinzu, selbst im Falle von Ausnahmen wird 'finally' block sicherstellen, dass yourTimer erneut gestartet wird. –