大约每分钟运行一次任务而不使用Thread.Sleep

时间:2015-12-03 18:34:16

标签: c# timer

我在C#中有一个我会运行的方法,然后等一下再重新启动该方法。

现在,我只是在使用

while(true)
{
    this.DoMyMethod();

    Thread.Sleep(TimeSpan.FromMinutes(1));
}

虽然这有效,但我想知道是否有更优雅的方式来做到这一点?计时器的问题是,即使最后一次计时器点火呼叫还没有完成,它们也会运行。

3 个答案:

答案 0 :(得分:8)

所以进行异步循环:

public async Task DoMyThing(CancellationToken token = default(CancellationToken))
{
     while(!token.IsCancellationRequested)
     {
         this.DoMyMethod();
         try
         {
             await Task.Delay(TimeSpan.FromMinutes(1), token);
         }
         catch(TaskCanceledException)
         {
             break;
         }
     }
}

此代码保证不会与DoMyMethod的调用重叠,因此延迟(与Thread.Sleep的方式大致相同)在调用之间发生

如果您创建CancellationTokenSource,则可以将Token传递给您的方法,并且可以通过调用Cancel上的CancellationTokenSource来终止循环。

注意:CancellationToken.None === default(CancellationToken)

答案 1 :(得分:4)

使用System.Timers.Timer,您可以将AutoReset设置为false,这意味着计时器只会运行一次,您必须再次拨打Start()才能重启。< / p>

因此,在您的计时器刻度方法中,只需在完成所需操作后再拨打Start(),然后您就可以重新开始了。

例如:

public SomeClass()
{
    Timer timer = new Timer(60000);
    timer.Elapsed += new ElapsedEventHandler(OnElapsed);
    timer.AutoReset = false;
    timer.Start();
}

private void OnElapsed(object sender, ElapsedEventArgs e)
{
    // Do stuff

    timer.Start(); // Restart timer
}

答案 2 :(得分:2)

计时器仍然是您的选择。如果您担心在第一个定时器触发过程完成之前再次跳闸,则在过程运行时停止定时器,然后在过程完成时重新启动它。