如何正确停止计时器

时间:2019-01-07 21:51:37

标签: c# timer locking

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)的执行指针将继续无限期地启动/停止计时器。在这种情况下如何处理计时器?

2 个答案:

答案 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个方法。另外,如果您最终需要跨平台支持或想要在处理过程中处理诸如取消之类的事情,那么我还将考虑使用stopTaskTask.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时重启计时器(即使引发异常)。

相关问题