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

我的foreach循环未遍历所有元素?C#定时器代码故障排查

问题描述

该代码旨在每100ms序列化所有对象并发送至其他程序,每200ms将序列化对象写入文件用于后续回放(另有代码负责读取这些文件)。但实际运行后,仅有“hammers”被输出,且仅打印0。已通过断点确认集合已正确填充,请问问题出在哪里?

原代码

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Helper
{
    public static class Program
    {
        public static bool active = false;
        public static WorldData wdataTest = new WorldData(); // Simple test objects
        public static Dictionary<string, WorldData> dic = new Dictionary<string, WorldData>();
        public static void Main()
        {
            active = true;
            Start();
        }

        public static void Start()
        {
            dic.Add("test", wdataTest);
            System.Timers.Timer timer = new System.Timers.Timer();
            string serialized;
            bool loaded = false;
            int i = -10;
            int normalizedRate = 2;
            timer.Interval = 100;
            timer.AutoReset = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler((_, __) => {
                try
                {
                    Stopwatch st = new Stopwatch();
                    st.Start();
                    if (active)
                    {
                        if (loaded)
                        {
                            i++;
                        }
                        foreach (WorldData wData in dic.Values)
                        {
                            loaded = true;
                            foreach (EntityList collection in wData.collectionOfCollections)
                            {
                                serialized = JsonConvert.SerializeObject(collection.Entities);
                                // Does some other things
                                if (i == normalizedRate)
                                {
                                    WriteSerialized(collection, serialized);
                                    i = 0;
                                }
                            }
                        }
                    }
                    st.Stop();
                    Console.WriteLine(st.ElapsedMilliseconds.ToString());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            });
            timer.Enabled = true;
            Console.ReadKey();
        }

        public static void WriteSerialized(EntityList collection, string serializedObj)
        {
            Console.WriteLine(collection.Name);
            // Write to file serializedObj
        }

        public class WorldData
        {
            public List<EntityList> collectionOfCollections;

            public WorldData()
            {
                collectionOfCollections = new List<EntityList>();
                collectionOfCollections.Add(new EntityList("hammers"));
                collectionOfCollections.Add(new EntityList("screwdrivers"));
                collectionOfCollections.Add(new EntityList("nails"));
                collectionOfCollections.Add(new EntityList("pcs"));
            }
        }

        public class EntityList
        {
            public List<object> Entities;
            public string Name { get; set; }
            public EntityList(string name)
            {
                Name = name;
                Entities = new List<object>();
                Entities.Add(new object());
            }
        }
    }
}
问题根源

1. 计数器逻辑错误导致仅单个集合触发写入

当i == normalizedRate(即i=2)时,处理第一个EntityList(hammers)后会立刻将i重置为0,后续的screwdrivers、nails、pcs循环时,i已经不满足等于2的条件,因此不会触发写入。

2. loaded变量逻辑混乱

loaded初始为false,第一次定时器触发时i不会递增,但进入WorldData循环后立即将loaded设为true,导致本次触发的后半段逻辑中loaded状态异常,后续计数逻辑混乱。

3. 多线程变量访问无同步

i、loaded、active这些变量在主线程定义,却在定时器的Elapsed线程中修改读取,没有线程同步机制,可能导致变量状态不可预期。

修复方案

调整逻辑,确保计数达标时所有集合都执行写入,同时保证线程安全:

修改后代码

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;

namespace Helper
{
    public static class Program
    {
        public static bool active = false;
        public static WorldData wdataTest = new WorldData();
        public static Dictionary<string, WorldData> dic = new Dictionary<string, WorldData>();
        private static readonly object _lockObj = new object(); // 线程同步锁
        public static void Main()
        {
            active = true;
            Start();
        }

        public static void Start()
        {
            dic.Add("test", wdataTest);
            System.Timers.Timer timer = new System.Timers.Timer();
            string serialized;
            int i = 0;
            int normalizedRate = 2;
            timer.Interval = 100;
            timer.AutoReset = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler((_, __) => {
                try
                {
                    Stopwatch st = new Stopwatch();
                    st.Start();
                    lock (_lockObj)
                    {
                        if (active)
                        {
                            i++;
                            bool needWrite = i == normalizedRate;

                            foreach (WorldData wData in dic.Values)
                            {
                                foreach (EntityList collection in wData.collectionOfCollections)
                                {
                                    serialized = JsonConvert.SerializeObject(collection.Entities);
                                    // 执行序列化后的发送逻辑

                                    if (needWrite)
                                    {
                                        WriteSerialized(collection, serialized);
                                    }
                                }
                            }

                            if (needWrite)
                            {
                                i = 0;
                            }
                        }
                    }
                    st.Stop();
                    Console.WriteLine(st.ElapsedMilliseconds.ToString());
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            });
            timer.Enabled = true;
            Console.ReadKey();
        }

        public static void WriteSerialized(EntityList collection, string serializedObj)
        {
            Console.WriteLine(collection.Name);
            // Write to file serializedObj
        }

        public class WorldData
        {
            public List<EntityList> collectionOfCollections;

            public WorldData()
            {
                collectionOfCollections = new List<EntityList>();
                collectionOfCollections.Add(new EntityList("hammers"));
                collectionOfCollections.Add(new EntityList("screwdrivers"));
                collectionOfCollections.Add(new EntityList("nails"));
                collectionOfCollections.Add(new EntityList("pcs"));
            }
        }

        public class EntityList
        {
            public List<object> Entities;
            public string Name { get; set; }
            public EntityList(string name)
            {
                Name = name;
                Entities = new List<object>();
                Entities.Add(new object());
            }
        }
    }
}

关键修改点

  • 移除冗余的loaded变量,每次定时器触发直接递增i
  • 提前判断本次是否需要写入(needWrite),确保所有集合都能执行写入操作
  • 所有集合处理完成后再重置i,避免中断后续集合的写入逻辑
  • 添加lock语句,保证多线程下变量访问的安全性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:35:28