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

C# System.Timers.Timer长期运行后出现重叠日志问题求助

C# WinForm定时器长期运行后出现重复日志问题

我开发了一个C# WinForm程序,使用System.Timers.Timer每秒执行一次变量检查、日志记录,满足条件时触发后续函数。程序连续运行超过两周后,出现定时器日志重叠问题:定时器周期为1秒,但日志中同一秒内多次输出相同内容(如示例中14:06:05多次输出B)。

已排查情况

  • 在问题出现的相同环境测试程序,未复现症状;
  • 同时运行多个程序实例,未复现症状;
  • 异步添加多个同类型定时器,日志功能失效;
  • 未找到同类症状的公开案例。

相关代码

定时器初始化代码

该初始化方法仅在程序启动(Form_load())时调用一次。

private static System.Timers.Timer TestEndDetection_Timer_;

private void SetUp_TestEndDetection_Timer_()
{
    TestEndDetection_Timer_ = new System.Timers.Timer(1000);
    TestEndDetection_Timer_.Elapsed += TestEndDetection_Timer_Event;
    TestEndDetection_Timer_.AutoReset = true;
    TestEndDetection_Timer_.Enabled = true;
}

定时器事件处理代码

private void TestEndDetection_Timer_Event(Object source, ElapsedEventArgs e)
{
    defrostCount++;
    CheckForIllegalCrossThreadCalls = false;
    
    if (NowTesting && AutoDefrost && checkBox2.Checked)
    {
        TestEndDetectionDealyTimer++;
        
        if (TestEndDetectionDealyTimer > 180)
        {
            bool Fix1End = false;
            bool Fix2End = false;
            bool Fix3End = false;
            bool Fix4End = false;
            bool Fix5End = false;
            bool Fix6End = false;

            bool Fix1Done = false;
            bool Fix2Done = false;
            bool Fix3Done = false;
            bool Fix4Done = false;
            bool Fix5Done = false;
            bool Fix6Done = false;

            bool Fix1Power = false;
            bool Fix2Power = false;
            bool Fix3Power = false;
            bool Fix4Power = false;
            bool Fix5Power = false;
            bool Fix6Power = false;

            Fix1Done = File.Exists(@"Z:\result\fix1\hdiag.log");
            Fix2Done = File.Exists(@"Z:\result\fix2\hdiag.log");
            Fix3Done = File.Exists(@"Z:\result\fix3\hdiag.log");
            Fix4Done = File.Exists(@"Z:\result\fix4\hdiag.log");
            Fix5Done = File.Exists(@"Z:\result\fix5\hdiag.log");
            Fix6Done = File.Exists(@"Z:\result\fix6\hdiag.log");

            defrostlogger("TESTDONE: "+Convert.ToInt32(Fix1Done) + "/" + Convert.ToInt32(Fix2Done) + "/" + Convert.ToInt32(Fix3Done) + "/" + Convert.ToInt32(Fix4Done) + "/" + Convert.ToInt32(Fix5Done) + "/" + Convert.ToInt32(Fix6Done));

            Fix1Power = m_ucFixInfo[1].PowerStat;
            Fix2Power = m_ucFixInfo[2].PowerStat;
            Fix3Power = m_ucFixInfo[3].PowerStat;
            Fix4Power = m_ucFixInfo[4].PowerStat;
            Fix5Power = m_ucFixInfo[5].PowerStat;
            Fix6Power = m_ucFixInfo[6].PowerStat;
           
            defrostlogger("POWER: "+Convert.ToInt32(Fix1Power) + "/" + Convert.ToInt32(Fix2Power) + "/" + Convert.ToInt32(Fix3Power) + "/" + Convert.ToInt32(Fix4Power) + "/" + Convert.ToInt32(Fix5Power) + "/" + Convert.ToInt32(Fix6Power));
            
            
            if (Fix1Done || !Fix1Power) { Fix1End = true; } else { Fix1End = false; }
            if (Fix2Done || !Fix2Power) { Fix2End = true; } else { Fix2End = false; }
            if (Fix3Done || !Fix3Power) { Fix3End = true; } else { Fix3End = false; }
            if (Fix4Done || !Fix4Power) { Fix4End = true; } else { Fix4End = false; }
            if (Fix5Done || !Fix5Power) { Fix5End = true; } else { Fix5End = false; }
            if (Fix6Done || !Fix6Power) { Fix6End = true; } else { Fix6End = false; }
                                       
            if (Fix1End && Fix2End && Fix3End && Fix4End && Fix5End && Fix6End && AutoDefrostRunStat && TestEndCount < 20)
            {
                TestEndCount++;
            }
                                       
            if (TestEndCount > 10)
            {
                if (button13.Text == "Door Open" && DefrostAvailable)
                {
                    defrostlogger("A");
                    RunDefrost();
                    AutoDefrostRunStat = false;
                    NowTesting = false;
                    TestEndCount = 0;
                }
                else
                {
                    defrostlogger("B");
                }
            }
        }
    }
    else
    {
        if (defrostCount % 10 == 9 && NowTesting)
        {
            Load_SV_txt();
            defrostCount = 0;
        }
    }
}

日志记录方法

private void defrostlogger(string msg)
{
    using (System.IO.StreamWriter file_ = new System.IO.StreamWriter(Application.StartupPath + @"\Logs\DefrostLog_" + System.DateTime.Now.ToString("MM_dd") + ".txt", true))
    {
        file_.WriteLine("[" + System.DateTime.Now.ToString("HH:mm:ss") + "]" + msg);
    }
}

排查与解决建议

  • 解决定时器重入问题:System.Timers.Timer在AutoReset=true时,若前一次事件处理耗时超过1秒,会触发新的线程执行事件逻辑,导致同一周期内多次执行。可以通过加锁或修改定时器模式避免:
    方案一:添加锁避免重入
    private static readonly object TimerLock = new object();
    private void TestEndDetection_Timer_Event(Object source, ElapsedEventArgs e)
    {
        if (!Monitor.TryEnter(TimerLock)) return;
        try
        {
            // 原有逻辑代码
        }
        finally
        {
            Monitor.Exit(TimerLock);
        }
    }
    
    方案二:关闭自动重置,手动触发下一次
    private void SetUp_TestEndDetection_Timer_()
    {
        TestEndDetection_Timer_ = new System.Timers.Timer(1000);
        TestEndDetection_Timer_.Elapsed += TestEndDetection_Timer_Event;
        TestEndDetection_Timer_.AutoReset = false;
        TestEndDetection_Timer_.Enabled = true;
    }
    
    private void TestEndDetection_Timer_Event(Object source, ElapsedEventArgs e)
    {
        try
        {
            // 原有逻辑代码
        }
        finally
        {
            TestEndDetection_Timer_.Start();
        }
    }
    
  • 优化日志时间精度:将日志时间格式改为HH:mm:ss.fff,添加毫秒级精度,便于区分事件实际触发时间,排查是否真的是同一秒内多次执行。
  • 修复线程安全问题:全局变量defrostCount、TestEndDetectionDealyTimer等未做线程同步,长期运行可能出现值异常,建议用Interlocked类操作或加锁保护。
  • 优化耗时操作:事件中访问网络路径Z盘的File.Exists可能因网络延迟导致处理超时,可将该逻辑异步化,避免阻塞定时器线程。
  • 监控系统资源:长期运行后系统负载、内存泄漏可能影响定时器调度,添加内存、线程池状态监控,排查资源异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:25:30