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

C# Windows Service重复读取已处理记录,疑似内存未清除问题求助

问题排查:Windows Service重复读取已处理记录

我是Windows Service与C#开发新手,开发的Windows Service需读取数据库表数据,转为JSON后发送至外部接口,成功接收返回结果后更新本地标记以标识记录已处理。目前遇到的问题:定时器首次启动时能正确筛选未标记记录并处理;但定时器间隔运行时,仍会读取已处理的同批记录,疑似上一次运行的内存未被清除。

现有代码

OnStart方法

protected override void OnStart(string[] args)
{
    try
    {
        log.Info("Starting the service");
        
        T = new System.Timers.Timer();
        T.Enabled = true;
        T.Elapsed += new ElapsedEventHandler(OnElapsedHandler);
        T.Interval = scheduledTime;
    }
    
    catch(Exception e)
    {
        log.info(e.message());
    }
}

OnElapsedHandler方法

private void OnElapsedHandler(object sender, System.Timers.ElapsedEventArgs e)
{
    //String path = @"E:\Program\JobRun.txt";
    // Check the local time
    ESTBranches = ConfigurationManager.AppSettings["EST"].ToString().Split(',');
    CSTBranches = ConfigurationManager.AppSettings["CST"].ToString().Split(',');
    MSTBranches = ConfigurationManager.AppSettings["MST"].ToString().Split(',');
    PSTBranches = ConfigurationManager.AppSettings["PST"].ToString().Split(',');

    DateTime currentDateTimeUTC = DateTime.UtcNow;
    int hour = Int32.Parse(currentDateTimeUTC.ToString("HH"));

    List<Model_Parts> lstParts = new List<Model_Parts>();
    lstParts = mwQ.GetPartsQueue(); // Get list of unprocessed parts in MW from MB

    Auth auth = new Auth();

    double elapsedMillisecs = ((TimeSpan)(DateTime.Now - auth.GenerateTime)).TotalMilliseconds;

    if (elapsedMillisecs > 3600000 || auth.AuthToken.Trim().Length == 0)
    {
        sfsOps.GetSFSAccessToken();
    }

    sfsOps.BuildPartsJSON("Create", lstParts);
}

排查与解决思路

  • 排除内存缓存问题:lstParts是方法内的局部变量,每次定时器触发都会重新创建并赋值,不存在上一次数据残留的情况,问题与内存清理无关。
  • 检查标记更新逻辑:代码中仅调用了sfsOps.BuildPartsJSON发送数据,但未看到接口返回成功后更新数据库标记的代码。如果缺失这一步,数据库中记录始终是未处理状态,mwQ.GetPartsQueue()会重复读取同批数据。
  • 验证GetPartsQueue()查询逻辑:
    • 确认该方法的SQL查询是否正确筛选未标记记录(例如WHERE IsProcessed = 0)。
    • 如果mwQ是全局实例,检查其内部是否存在缓存机制(如将查询结果存在全局变量中未重新查询),需确保每次调用都重新读取数据库。
  • 处理定时器并发问题:System.Timers.Timer默认多线程触发,若前一次处理未完成就触发下一次,可能导致重复读取。可修改定时器逻辑避免并发:
    private void OnElapsedHandler(object sender, System.Timers.ElapsedEventArgs e)
    {
        var timer = (System.Timers.Timer)sender;
        timer.Enabled = false; // 先禁用定时器,避免并发
        
        try
        {
            // 原有业务逻辑
            
            // 确认接口调用成功后,执行数据库标记更新
            // mwQ.UpdateProcessedStatus(lstParts); // 需补充此方法实现
        }
        finally
        {
            timer.Enabled = true; // 处理完成后重新启用定时器
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:33:09