You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派Linux Mono环境下,如何检测系统时间变化修复WinForms Timer暂停问题

解决Mono环境下System.Windows.Forms.Timer因系统时间校正停止的问题

问题原因

System.Windows.Forms.Timer是依赖WinForms消息循环的定时器,它通过计算绝对系统时间来触发Tick事件。当NTP将快进的系统时间回拨校正时,定时器会认为下一次触发的时间还未到来,因此会暂停触发,直到系统时间走到原本预期的“未来时间”才恢复。

解决方案

方案1:替换为不受绝对时间影响的定时器

使用System.Timers.Timer或System.Threading.Timer,这类定时器基于实际流逝的时间间隔触发,不受系统时间回拨的影响。注意:非WinForms定时器的触发事件在非UI线程,更新界面时需要通过Invoke切换到UI线程。

示例代码(替换为System.Timers.Timer):

private System.Timers.Timer _logTimer;

public void Form1_Load(object sender, EventArgs e)
{
    _logTimer = new System.Timers.Timer(100);
    _logTimer.Elapsed += LogTimer_Elapsed;
    _logTimer.Start();
}

private void LogTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    // 切换到UI线程更新控件
    this.Invoke((Action)(() =>
    {
        lblTime.Text = DateTime.Now.ToString("dd-MM-yy HH:mm:ss");
    }));
}

// 窗体关闭时释放资源
protected override void OnFormClosed(FormClosedEventArgs e)
{
    _logTimer?.Dispose();
    base.OnFormClosed(e);
}

方案2:检测系统时间变化,重置原有Timer

通过后台定时检查系统时间,当检测到时间回拨时,手动重置System.Windows.Forms.Timer。这里用System.Threading.Timer来做时间检测,因为它不受系统时间变化影响,能稳定执行检查逻辑。

示例代码:

private DateTime _lastCheckedTime;
private System.Threading.Timer _timeCheckTimer;

public Form1()
{
    InitializeComponent();
    _lastCheckedTime = DateTime.Now;
    // 每隔1秒检查一次系统时间
    _timeCheckTimer = new System.Threading.Timer(CheckSystemTimeChange, null, 0, 1000);
}

private void CheckSystemTimeChange(object state)
{
    DateTime currentTime = DateTime.Now;
    // 检测时间回拨(允许1秒误差,避免系统时间精度问题)
    if (currentTime < _lastCheckedTime.AddSeconds(-1))
    {
        // 在UI线程重置WinForms Timer
        this.Invoke((Action)(() =>
        {
            LogTimer.Stop();
            LogTimer.Start();
        }));
    }
    _lastCheckedTime = currentTime;
}

// 窗体关闭时释放检测定时器
protected override void OnFormClosed(FormClosedEventArgs e)
{
    _timeCheckTimer?.Dispose();
    base.OnFormClosed(e);
}

注意事项

  • 若使用方案1,需确保所有UI操作都通过Invoke或BeginInvoke切换到UI线程,避免跨线程访问控件的异常。
  • 方案2的时间检测间隔可根据需求调整,1秒的间隔既能及时捕获时间变化,也不会占用过多系统资源。

内容的提问来源于stack exchange,提问作者pm101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:55:29