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();
}
}
在上面的代码中,我过去的事件(MyEventOnElapsed
)将需要一段时间才能完成,因此,我不得不使用计时器启动和停止作为该方法的一部分。假设触发MethodTriggeredToStopTimer
时,代码位于MyEventOnElapsed
并已锁定,但是MethodTriggerredToStopTimer
处的线程赢得了比赛并设法获得了锁定,我的计时器将被MethodTriggeredToStopTimer()
。但是,一旦释放了锁定,等待aLockObject
中的锁定(MyEventOnElapsed
)的执行指针将继续无限期地启动/停止计时器。在这种情况下如何处理计时器?
答案 0 :(得分:0)
如果您希望在管理这样的循环时通过方法调用或触发器来停止的确切方式,则需要维护一些boolean isStopped
或类似的内容:
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();
}
}
在一个不错的小型包装器类中,这一切将变得更加整洁,状态变量的名称类似Enabled
,以避免与Timer
的{{1}}的命名相似性和start
个方法。另外,如果您最终需要跨平台支持或想要在处理过程中处理诸如取消之类的事情,那么我还将考虑使用stop
,Task
和Task.Delay
构建此循环长时间运行的操作。
答案 1 :(得分:0)
一种选择是询问计时器Timer
是否已启用,然后再停止(禁用)它。 这样,如果调用MethodTrigerredToStopTimer
,它将意识到它已被故意停止,而不会再次启动。
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();
}
}
}
}
try finally
有助于确保在退出lock
时重启计时器(即使引发异常)。