gpt4 book ai didi

c# - 调用 timer.Stop() 后执行的 System.Timers.Timer Elapsed 事件

转载 作者:可可西里 更新时间:2023-11-01 08:15:59 27 4
gpt4 key购买 nike

背景: 我有一个计时器,我用它来跟踪自 serialPort DataReceived 事件被触发以来已经过了多长时间。我正在为此创建自己的解决方案而不是使用内置的超时事件,因为我正在获取连续的数据流,而不是发送查询并获得一个响应。

问题:在 DataReceived 处理程序中,我有一个停止计时器的语句,这样它就不会过去。问题是很多时候它仍然执行 Elapsed 处理程序后记。

我读到可以使用 SynchronizingObject 来解决这个问题,但我不确定如何实现。

这是我的代码:我试图删除所有我认为不相关的内容。

    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));

}

最佳答案

这是众所周知的行为。 System.Timers.Timer 内部使用ThreadPool 来执行。运行时会将 Timer 放入线程池中。它会在您调用 Stop 方法之前就已经排队。它将在耗时触发。

为避免这种情况发生,请将 Timer.AutoReset 设置为 false,并在需要时在经过的处理程序中重新启动计时器。将 AutoReset 设置为 false 会使计时器仅触发一次,因此为了让计时器按间隔触发,请手动再次启动计时器。

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();
}
}

关于c# - 调用 timer.Stop() 后执行的 System.Timers.Timer Elapsed 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18280330/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com