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

序列化时遇“集合已修改”错误,如何定位目标集合?

定位Json.NET序列化时被修改的集合

我之前也碰到过一模一样的糟心事——序列化包含大量列表和属性的大型对象时,因为某个集合在遍历(序列化)过程中被修改,直接触发了异常。分享几个我亲测有效的排查方法,尤其是适合在即时窗口里快速定位的技巧:

即时窗口专属排查命令

  • 锁定检测法:在异常触发的断点处,你可以通过检测集合是否被其他线程锁定来判断是否正在被修改。在即时窗口里运行这段代码,能自动遍历myObj里的所有集合类型属性,找出疑似被修改的目标:
    foreach(var prop in myObj.GetType().GetProperties().Where(p => typeof(System.Collections.IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType != typeof(string))) 
    { 
        var col = prop.GetValue(myObj); 
        if(col != null && !System.Threading.Monitor.TryEnter(col, 0)) 
        { 
            Console.WriteLine($"疑似被修改的集合:{prop.Name}"); 
        }
    }
    
    原理是:如果集合正在被修改,通常会被修改线程锁定,Monitor.TryEnter会返回false。
  • 版本号追踪法:像List<T>、HashSet<T>这类.NET内置集合,内部都有一个_version私有字段——每次集合被修改(添加/删除/清空),这个数值都会递增。在即时窗口里直接查看这个值,多次执行如果数值变化,就说明这个集合在被修改:
    // 把YourType换成集合实际的元素类型
    ((System.Collections.Generic.List<YourType>)myObj.TargetListProperty)._version
    

额外调试辅助技巧

  • 用可视化工具实时监控:在Visual Studio调试窗口中,右键点击可疑集合,选择“可视化”→“集合可视化器”,可以实时观察集合的元素数量和内容变化,序列化过程中如果有变动一眼就能看到。
  • 给集合加临时日志:在JsonConvert.SerializeObject前后,给每个重要集合记录Count值和哈希码,如果序列化后数值和之前不一致,那这个集合就是问题所在。
  • 在集合修改方法上加断点:如果是自定义集合,直接在Add/Remove方法上设断点;如果是内置集合,可以通过Visual Studio的“断点→新建断点→函数断点”,输入System.Collections.Generic.List1.Add`来给所有List的Add方法加断点,触发时查看调用栈就能找到修改集合的线程和代码位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:30