我在C#中有一个我会运行的方法,然后等一下再重新启动该方法。
现在,我只是在使用
while(true)
{
this.DoMyMethod();
Thread.Sleep(TimeSpan.FromMinutes(1));
}
虽然这有效,但我想知道是否有更优雅的方式来做到这一点?计时器的问题是,即使最后一次计时器点火呼叫还没有完成,它们也会运行。
答案 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)
计时器仍然是您的选择。如果您担心在第一个定时器触发过程完成之前再次跳闸,则在过程运行时停止定时器,然后在过程完成时重新启动它。