捕获倒计时或滴答事件 - Threading.Timer C#

Posted

技术标签:

【中文标题】捕获倒计时或滴答事件 - Threading.Timer C#【英文标题】:Capture Countdown or Tick Event - Threading.Timer C# 【发布时间】:2021-12-10 19:42:30 【问题描述】:

我开发了一个程序,使用Threading.Timer 在 30 秒后调用一个方法。

该方法正在被调用,它正在工作,但我想获取该事件,以便知道 30 秒还剩多少秒。

我需要一种每秒钟触发一次的滴答事件。这样我也可以显示剩余的秒数。这是我的代码:

Timer timerObj;

timerObj = new Timer(UpdateUI, null, Timeout.Infinite, Timeout.Infinite);
timerObj.Change(30000, Timeout.Infinite);


public void UpdateUI(object state)

    ShowQR= false;

我怎么才能倒计时呢?

【问题讨论】:

也许添加一个Stopwatch 来跟踪经过的时间和另一个Timer 每秒触发一次左右?然后该计时器的处理程序可以使用Stopwatch 来确定经过的时间,从而确定剩余时间。 @MatthewWatson - 你的想法似乎很棒。能不能写出来方便我补充。 您也可以使用您现在拥有的相同计时器(但有 1 秒滴答),并且不是在每次滴答时更新 UI,而是在经过的时间超过 30 秒时更新 UI。 其实我更喜欢 Evk 的建议——它避免了有两个计时器。 用时钟测量经过的时间,DateTime.UtcNow 很好。您只需要一个计时器来刷新 UI。它的间隔并不重要,100 毫秒是一个不错的选择。优于 1 秒,这往往会考验奈奎斯特的采样定理。并使用正确的 种类 计时器来更新 UI,例如 System.Windows.Forms.Timer 或 DispatcherTimer,这样您就不必担心线程安全问题。 【参考方案1】:

这就是您实施 Evk 建议的方式:

Timer timerObj;
Stopwatch stopwatch;

...

timerObj = new Timer(UpdateUI, null, Timeout.Infinite, Timeout.Infinite);
timerObj.Change(1000, Timeout.Infinite);
stopwatch = Stopwatch.StartNew();

public void UpdateUI(object state)

    if (stopwatch.Elapsed < TimeSpan.FromSeconds(30))
       
         timerObj.Change(1000, Timeout.Infinite);
         return;
       
        
    stopwatch.Restart();    
    ShowQR= false;

注意如何在调用timerObj.Change() 启动计时器的同时启动Stopwatch

还要注意如何将计时器设置为每秒触发一次,而不是每 30 秒触发一次。

然后在计时器处理程序中,您只需检查 Stopwatch 上的经过时间 - 如果小于 30 秒,则返回;否则,请每 30 秒执行一次您想做的事情并(重要!)重新启动 Stopwatch

【讨论】:

以上是关于捕获倒计时或滴答事件 - Threading.Timer C#的主要内容,如果未能解决你的问题,请参考以下文章

为啥有时在计时器滴答事件中它会连续两次调用该方法?

使用计时器事件,表单不会顺利调整大小

为啥我的计时器停止滴答作响?

定时器触发 Tick 事件,延迟 15 毫秒

将屏幕截图捕获为图像然后使用 ffmpeg 将图像转换为视频文件的时间应该是啥?

websocket计时器滴答后提升asio短读错误