C# 如何正确停止计时器
在上面的代码中,我的已用事件(C# 如何正确停止计时器,c#,timer,locking,C#,Timer,Locking,在上面的代码中,我的已用事件(myeventonappeased)需要一段时间才能完成,因此我必须使用计时器启动和停止作为该方法的一部分。当触发methodTriggeredToOptimer时,让我们假设代码在MyEventOn运行并达到锁,但是MethodTriggeredToStopTimer处的线程赢得比赛并设法获得锁,我的计时器将被methodTriggeredTopTimer()停止。但是,一旦释放锁,等待在MyEventOnAppead中的锁(aLockObject)处的执行指针将
myeventonappeased
)需要一段时间才能完成,因此我必须使用计时器启动和停止作为该方法的一部分。当触发methodTriggeredToOptimer
时,让我们假设代码在MyEventOn运行
并达到锁,但是MethodTriggeredToStopTimer
处的线程赢得比赛并设法获得锁,我的计时器将被methodTriggeredTopTimer()
停止。但是,一旦释放锁,等待在MyEventOnAppead
中的锁(aLockObject
)处的执行指针将继续无限期地启动/停止计时器。在这种情况下如何处理计时器?如果您想在管理这样的循环时通过方法调用或触发器确定停止方式,则需要维护一些布尔值或类似值:
using System.Timers;
void CreateTimer()
{
myTimerObject = new Timer(5000);
myTimerObject.AutoReset = false;
myTimerObject.Elapsed += MyEventOnElapsed;
myTimerObject.Start();
}
void MyEventOnElapsed(object sender, ElapsedEventArgs e)
{
lock(aLockObject)
{
myTimerObject.Stop();
// Perform actions that can exceed the interval time set in the timer
myTimerObject.Start();
}
}
void MethodTrigerredToStopTimer()
{
lock(aLockObject)
{
myTimerObject.Stop();
}
}
在一个漂亮的小包装器类中,这一切都会更加整洁,状态变量的名称类似于Enabled
,以避免与计时器的start
和stop
方法的命名相似性混淆。此外,我还将研究如何使用Task
,Task.Delay
,构建这个循环,如果您最终需要跨平台支持或希望在长时间运行操作期间处理取消之类的事情,也可以使用CancellationToken
。一个选项是在停止(禁用)计时器之前询问计时器是否启用了计时器。这样,如果调用了methodTrigerredToOptimer
,它将意识到它是故意停止的,而不会再次启动它
try finally
有助于确保在退出锁时重新启动计时器(即使引发异常)。System.Threading.timer、System.Timers.timer或System.Windows.Forms.timer?System.Timers.timer
boolean isStopped = false;
void CreateTimer()
{
myTimerObject = new Timer(5000);
myTimerObject.AutoReset = false;
myTimerObject.Elapsed += MyEventOnElapsed;
myTimerObject.Start();
}
void MyEventOnElapsed(object sender, ElapsedEventArgs e)
{
lock(aLockObject)
{
if (isStopped)
return;
myTimerObject.Stop();
// Perform actions that can exceed the interval time set in the timer
myTimerObject.Start();
}
}
void MethodTrigerredToStopTimer()
{
lock(aLockObject)
{
isStopped = true;
myTimerObject.Stop();
}
}
void MyEventOnElapsed(object sender, ElapsedEventArgs e)
{
lock(aLockObject)
{
if (myTimerObject.Enabled)
{ try
{
myTimerObject.Stop();
// Perform actions that can exceed the interval time set in the timer
}
finally
{
myTimerObject.Start();
}
}
}
}