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

C#后台服务同步电表历史数据MySQL写入行数超出预期问题咨询

问题根因

1. StringBuilder未每次循环清空(核心原因,完全匹配你给出的行数异常规律)

你将SqlQuery实例化写在了day循环的外层,且每次循环结束后没有清空内容:

  • 第1次day循环:拼接1条INSERT语句,执行插入1行,累计1行
  • 第2次day循环:在上一次的基础上追加第2条INSERT,此时SQL包含2条语句,执行插入2行,累计3行
  • 第3次day循环:再追加第3条INSERT,此时SQL包含3条语句,执行插入3行,累计6行
    最终总插入行数为1+2+...+n = n(n+1)/2,和你描述的数值完全吻合:n=3得6、n=4得10、n=5得15、n=6得21。

2. 循环变量闭包捕获问题

你在foreach循环中直接将捕获了Router、Meter循环变量的委托加入actionList,C# 5.0之前的版本中,foreach循环的迭代变量是全局作用域,所有委托捕获的都是同一个变量的引用,等到Parallel.Invoke执行时,变量值已经被后续迭代覆盖,会导致同一个电表被重复执行多次插入。

3. async void方法 + Parallel.Invoke 逻辑错误

GetHistory被声明为async void,这类异步方法无法被调用方追踪执行状态,Parallel.Invoke只会等待委托的同步部分执行完成,不会等待异步IO结束,就会执行后续的actionList.Clear()、进入下一轮60秒周期的循环,导致上一轮还没执行完的插入逻辑和新一轮的逻辑叠加,重复插入数据。

4. 模型实例未重置

mcReadings实例化在day循环外层,每次循环只会覆盖属性值,若部分属性未被赋值,会携带上一次循环的旧值,导致错误数据插入,极端情况也会触发重复插入逻辑。


修复方案

  1. 每次day循环清空StringBuilder,或者直接将SqlQuery的实例化移到day循环内部:
for (int day = 1; day < 4; day++)
{
    StringBuilder SqlQuery = new StringBuilder();
    // 剩余逻辑不变
}
  1. 修复闭包问题,在循环内定义局部变量保存迭代值:
foreach (PowerMeterModel Meter in Meters.Where(x => x.IdGateway == Router.Id).ToList())
{
    if (Meter.IsActive)
    {
        // 定义局部变量捕获当前迭代的值
        var currentRouter = Router;
        var currentMeter = Meter;
        actionList.Add(new Action(() =>
        {
            GetHistory(currentRouter, currentMeter);
            _logger.LogInformation("Synced History meter:" + currentMeter.SerialNumber.ToString());
        }));
    }
}
  1. 替换async void为async Task,改用异步并行等待,不要用Parallel.Invoke处理IO密集型任务:
// 将GetHistory签名改为
public async Task GetHistory(RouterModel Router, PowerMeterModel Meter)
{
    // 原有逻辑不变
}

// 执行部分替换Parallel.Invoke为:
var tasks = actionList.Select(action => Task.Run(action));
await Task.WhenAll(tasks);
  1. 将mcReadings实例化移到day循环内部,避免旧值残留。
  2. 不要手动拼接SQL语句,改用参数化查询,避免SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:45:05