在不使用Thread.Sleep的情况下,大约每分钟运行一个任务
本文关键字:运行 每分钟 任务 一个 Thread Sleep 情况下 | 更新日期: 2023-09-27 18:25:42
我在C#中有一个要运行的方法,然后等待一分钟再重新启动该方法。
现在,我只是在使用
while(true)
{
this.DoMyMethod();
Thread.Sleep(TimeSpan.FromMinutes(1));
}
虽然这很有效,但我想知道是否有更优雅的方法可以做到这一点?定时器的问题是,即使最后一个定时器火警还没有结束,它们也会运行。
所以做一个异步循环:
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
传递给您的方法,并可以通过在CancellationTokenSource
上调用Cancel
来终止循环。
注:CancellationToken.None === default(CancellationToken)
使用System.Timers.Timer
,您可以将AutoReset
设置为false
,这意味着计时器只运行一次,您必须再次调用Start()
才能重新启动它。
因此,在您的计时器刻度方法中,只需在完成所需操作并准备重新开始后调用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
}
计时器仍然是您的选择。如果您担心它在第一个计时器启动过程完成之前再次跳闸,请在进程运行时停止计时器,然后在进程完成时重新启动。