【问题标题】:Behaviour of System.Timer when Interval property changed间隔属性更改时 System.Timer 的行为
【发布时间】:2010-05-05 18:48:33
【问题描述】:

我有一个 System.Timer 设置来每天凌晨 2 点触发一个事件。 如果计时器启动的过程失败,那么我想要计时器 重置为每 15 分钟运行一次,直到该过程成功完成。

// this is how the timer is set up. 
// this is working correctly.

double startTime = milliseconds_of_hour_to_start.

Timer = new System.Timers.Timer( startTime);

这是在事件处理程序成功或失败时重置计时器的代码。 注意计时器没有停止, 只是 Interval 属性正在重置。

if (ProcessSuccess)
{
  Timer.Interval = TimeSpan.FromHours(24).TotalMilliseconds;
}
else
{
  Timer.Interval = TimeSpan.FromMinutes(15).TotalMilliseconds;
}

我的问题是,如果这个过程失败了 4 次,那么定时器现在会在凌晨 3 点左右运行吗? 即失败后,凌晨 2 点的原始开始时间会提前 15 分钟吗?

【问题讨论】:

  • 未来的实现可能值得关注quartznet.sourceforge.net。我总是更喜欢查看现有的可以重用的库而不是自己编写的库

标签: .net timer


【解决方案1】:

我鼓励您download Reflector,您会找到此类问题的快速答案。计时器的间隔由 TimerBase.ChangeTimer() 更改。采取多种措施来确保间隔更新的安全和准确。代码在 finally 块中运行,因此即使是 ThreadAbortException 也不会搞砸。它获取一个锁(m_lock 成员)以确保跨线程序列化访问。 ChangeTimerNative() 调用调用 CLR 以更新本机计时器。该方法由 TimerNative::CorChangeTimer() 实现,它调用 ChangeTimerQueueTimer() Windows API 函数。该函数被证明是安全的,即使从 Elapsed 回调函数内部调用也是如此。

长话短说,是的:它具有您正在寻找的行为。但是请注意不可避免的竞争条件,计时器可能已经过去,并且进行回调的线程池线程可能已经安排运行但还没有机会运行。更改定时器后立即获取回调并非不可能。

【讨论】:

    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    相关资源
    最近更新 更多