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

C#实现观察者模式遍历集合报集合已修改枚举操作异常

异常产生原因
  • 直接触发点:你在遍历animals集合的foreach循环内部执行了animals.Remove()修改原集合的操作。.NET 中List<T>的枚举器有内置状态校验,只要枚举过程中原集合发生新增、删除元素的操作,就会直接抛出该异常。你之前尝试ToList()/ToArray()方案无效,是因为没有把快照逻辑用对位置,也没有把修改原集合的操作移出遍历周期。
  • 代码逻辑错误:你当前stock == 0分支的删除逻辑写在了遍历animals的循环块内部,属于典型的「边遍历边修改原集合」场景,必然触发枚举校验异常。
  • 隐藏隐患:所有遍历observers集合调用观察者回调的位置,如果观察者在OnNext/OnCompleted回调中执行Unsubscribe()操作,会直接修改observers原集合,同样会触发同类异常,只是当前测试场景没有走到该路径。
  • 附带逻辑bug:StockScreen的OnNext方法中,处理库存为0的动物时,刚把待删除项加入临时列表就立刻清空临时列表,导致本地缓存的下架动物信息永远无法被清理。
修复步骤
  1. 重构stock == 0分支的逻辑,严格遵循「先遍历原集合快照收集待处理项→遍历观察者快照发通知→遍历完成后统一修改原集合」的流程,彻底把遍历和修改操作隔离开:
else if (stock == 0)
{
    var animalsToRemove = new List<Animal>();
    // 遍历前对animals做快照,避免枚举过程受原集合修改影响
    foreach(var animal in animals.ToList()) 
    {
        if(info.AnimalId == animal.AnimalId)
        {
            animalsToRemove.Add(animal);
        }
    }
    // 通知观察者前对observers做快照,避免观察者回调中取消订阅触发集合修改异常
    foreach (var observer in observers.ToList())
    {
        observer.OnNext(info);
    }
    // 所有遍历、通知操作完成后,再统一删除原集合中的元素
    foreach (var animalToRemove in animalsToRemove)
    {
        animals.Remove(animalToRemove);
    }
}
  1. 修复所有遍历观察者集合的位置,统一加快照逻辑,覆盖所有通知路径:
  • 新增动物成功后的通知代码修改为:
animals.Add(info); 
foreach (var observer in observers.ToList())
{
    observer.OnNext(info);
}
  • LastAnimalBought方法中的完成通知修改为:
public void LastAnimalBought()
{
    foreach (var observer in observers.ToList())
    {
        observer.OnCompleted(); 
    }
    observers.Clear(); 
}
  1. 修复StockScreen中下架动物的本地缓存清理逻辑,修正临时列表清空时机:
if (info.AnimalStock == 0)
{
    var animalsToRemove = new List<string>();
    string name = String.Format("{0,5}", info.AnimalId); 
    // 遍历本地缓存快照收集待删除项
    foreach(var animalInfo in animalInfos.ToList())
    {
        if (animalInfo.Substring(21, 5).Equals(name))
        {
            animalsToRemove.Add(animalInfo); 
        }
    }
    // 统一删除本地缓存中的下架项
    foreach (var item in animalsToRemove)
    {
        animalInfos.Remove(item);
        updated = true;
    }
    animalsToRemove.Clear();
}

内容的提问来源于stack exchange,提问作者Dennis.b

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:24:15