任务执行时间高于定时器执行时间

问题描述:

我想澄清一下可能的代码实现,以防在使用timerDoJob_Elapsed执行的代码变长时它应该如何。 所以当下次计时器启动时,所有的内部事物都会被篡改/取消等等。任务执行时间高于定时器执行时间

这种问题有什么模式吗? 任何线索,使其更加稳定?

private void timerDoJob_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    VeryLongTask1(); 
    VeryLongTask2(); 
    VeryLongTask3(); 
} 
+0

你问,如果它怎么取消任务会持续太久? –

+0

@SamIam不,我不是。其实任务应该及时完成,但下一次计时器的迭代不应该破坏以前的东西。 –

如果您使用System.Timers.Timer,关闭AutoReset。然后在Elapsed方法结束时重新启用计时器。

private void timerDoJob_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    VeryLongTask1(); 
    VeryLongTask2(); 
    VeryLongTask3(); 
    mytimer.Enabled = true; 
} 

这样,定时器甚至不会再次启动,直到任务完成。但是请确保在try/catch块中的Elapsed方法中包含所有内容,因为如果发生未处理的异常,您的计时器将不会再次启动。

我以前用过的另一种方法是在你经过的事件,使用锁:

var myLock = new Object(); 
private void timerDoJob_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    lock (myLock) { 
    VeryLongTask1(); 
    VeryLongTask2(); 
    VeryLongTask3(); 
    } 
} 

这样,经过的事件的两个实例不能在同一时间运行。但是,有一点需要注意:如果任务需要比定时器的两次或更多次迭代更长的时间,则可以在后台添加迭代。例如,如果您的计时器在5秒后过去了,但您的任务需要60秒才能完成,但在第一次完成时,您将有11次等待。

Timer.Change方法给予Timeout.Infinite0作为参数会停止计时器(从MSDN):

如果duetime参数是零(0),回调方法被立即调用。如果 dueTime是Timeout.Infinite,则永远不会调用回调方法; 定时器被禁用,但可以通过调用Change和 指定dueTime的正值来重新启用。

一种可能,简单却不失强大的方法是停止计时器,直到整个任务已经结束,然后,再次启动定时器:

private void timerDoJob_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    timerDoJob.Change(Timeout.Infinite, 0); 

    // Use a try-finally so if some tasks throws an exception 
    // the timer will be re-enabled again anyway 
    try 
    { 
     VeryLongTask1(); 
     VeryLongTask2(); 
     VeryLongTask3(); 
    } 
    finally 
    { 
     timerDoJob.Change(0, 5000); 
    } 
}