如果上一次调用未完成,则不运行的.net计时器

本文关键字:运行 net 计时器 上一次 调用 未完成 如果 | 更新日期: 2023-09-27 18:24:42

我有一个程序需要每60秒做一次。这几乎总是需要1-2秒才能完成,但有一种情况可能需要几分钟。

有人知道一个.net定时器,如果上一次调用尚未完成,它将不会调用"时间流逝"方法吗?

很明显,我可以用这样的支票。。。

if(beingRun){

}

如果上一次调用未完成,则不运行的.net计时器

使用Enabled属性。

using System;
using System.Linq;
using System.Text;
using System.Timers;
namespace ConsoleApplication1
{
    internal class Program
    {
        private static readonly Timer MyTimer = new Timer()
        {
            Interval = 60,
        };
        private static void Main(string[] args)
        {
            MyTimer.Elapsed += MyTimerOnElapsed;
        }
        private static void MyTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            MyTimer.Enabled = false;
            try
            {
                // Some code here
            }
            finally
            {
                MyTimer.Enabled = true;
            }
        }
    }
}

您可以编写一个async方法来实现这一点:

public async void Recur(Action action, TimeSpan time, CancellationToken token)
{
    while(!token.IsCancellationRequested)
    {
        action();
        try
        {
            await Task.Delay(time, token);
        }
        catch(TaskCancelledException)
        {
            break;
        }
    }
}

并像一样使用

CancellationTokenSource cts = new CancellationTokenSource();
Recur(() => DoMyBigJob(), TimeSpan.FromMinutes(1), cts.Token);

并杀死它

cts.Token.Cancel();

不要丢失CancellationTokenSource,否则你会有一个失控的流氓异步循环。

我通常只存储计时器是否应该在bool中处理,如下所示:

Timer timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Interval = TimeSpan.FromSeconds(60).TotalMiliseconds;
bool processingSomething = false;
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
    if (!processingSomething)
    {
        processingSomething = true;
        // Process stuff here . . .
        processingSomething = false;
    }
}