【问题标题】:Timer auto restart after method finished方法完成后定时器自动重启
【发布时间】:2020-10-01 10:37:49
【问题描述】:

我在主程序中将计时器逻辑设置为每 30 秒一次 AutorReset,因此我的 LogCollection 方法(提取数据)将每 30 秒循环一次,并且我的代码可以继续运行。

问题是我意识到有时给定的时间比方法执行时间短,这会导致多个方法同时调用,从而导致多个数据泛滥。

问:如何让计时器在方法完成之前等待而不做另一个循环?

定时器代码如下:

        Timer thetimer = new Timer(TimeSpan.FromSeconds(30).TotalMilliseconds);
        thetimer.Elapsed += new System.Timers.ElapsedEventHandler(LogCollector.LogCollection);
        thetimer.AutoReset = true;
        thetimer.Start();

我正在考虑添加一些 While 循环,但我的代码将永远循环,其余代码将无法完成。 请指教

【问题讨论】:

  • .NET 中有许多名为 Timer 的类 - 您使用的是哪一个?
  • using System.Timers;

标签: c# timer


【解决方案1】:

我会放弃Timer 并改用async

while (true)
{
    var start = DateTime.Now;
    LogCollector.LogCollection();
    var timeRemaining = TimeSpan.FromSeconds(30) - (DateTime.Now - start);
    await Task.Delay(Math.Max(timeRemaining.TotalMilliseconds, 0));
}

Math.Max用于LogCollection()的执行时间超过30秒,此时timeRemaining为负数。

如果您有代码要在循环之后运行,请将其移至可取消的方法中:

async Task LogCollectionLoopAsync(TimeSpan minLoopTime, CancellationToken ct)
{
    while (!ct.IsCancellationRequested)
    {
        var start = DateTime.Now;
        LogCollector.LogCollection();
        var timeRemaining = minLoopTime - (DateTime.Now - start);
        await Task.Delay(Math.Max(timeRemaining.TotalMilliseconds, 0), ct);
    }
}

那么你的Main 方法可以这样写:

async Task Main()
{
    var cts = new CancellationTokenSource();

    var logCollectionTask = LogCollectionLoopAsync(TimeSpan.FromSeconds(30), cts.Token);

    // Do your other stuff

    cts.Cancel();

    try { await logCollectionTask;  } catch { } // Cancellation causes an exception
}

【讨论】:

  • 抱歉,我不知道为什么在最后一部分 (Main) 中,您在使用 try{ } 之前取消了 cts.Cancel();
  • @DanielA 取消延迟;没有它,循环将永远继续,Task 永远不会完成。
  • 但是如果我把取消放在那里,它可能会在任务实际完成之前取消它。我需要确保 LogCollection() 完成后才能取消。
  • 会的。 CancellationToken 只会取消延迟或下一次迭代,而不是LogCollection。注意令牌是如何传递给Task.Delay的;取消该令牌将导致Task.Delay 抛出异常,完成从LogCollectionLoopAsync 返回的Task
猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-05
  • 2012-10-21
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
相关资源
最近更新 更多