c# - 在字典的 linq 迭代过程中,什么可能导致堆栈溢出?

标签 c# linq multithreading dictionary stack-overflow

我有以下字典:

Dictionary<long, ChangeLogProcess> _changeLogProcesses = 
    new Dictionary<long, ChangeLogProcess>();

我有一个方法试图在字典中获取特定状态的下一个 changelogprocess(如果没有特定状态的项目则返回 null):

 var changeLogProcesses =
     from entry in _changeLogProcesses
     where (entry.Value.Status == status)
     select entry.Value;

 changeLogProcess = changeLogProcesses.FirstOrDefault<ChangeLogProcess>();

但是,在执行过程中,它在linq查询期间抛出堆栈溢出异常? 我做了很多测试以确保列表中有项目等等,但问题仍然存在?

值得注意的是,此方法是在多线程环境中运行的服务的一部分。上面的 linq 查询(以及对它的所有访问,例如添加/删除到列表的项目,或列表中项目的状态更改)都包含在 ReaderWriterLockSlim 写锁中。同样,我对它进行了广泛的调试,以确保在任何时候都只有一个线程访问列表。

什么可能导致它堆栈溢出,而不是一些可能的其他错误,例如在查询期间修改列表? (同样,我在任何时候都只有一个线程访问列表)

编辑:根据要求的 getter 和 setter 代码:

 public ChangeLogProcessStatus Status 
 {
    get { return _status; }
    set
    {
        //more that one place can initiate a retry now, so retry count is handled in the property setter
        if (PreviousStatus <= ChangeLogProcessStatus.Waiting && value >= ChangeLogProcessStatus.RetryWaiting)
        {
            this.ChangeLog.Tries++;

            //If it's retry waiting, remove this last service machine from the 
            //list so it can try it again because it's not an error
            if (value == ChangeLogProcessStatus.RetryWaiting && _previousServiceMachineIds.Count > 0)
            {   
                _previousServiceMachineIds.RemoveAt(_previousServiceMachineIds.Count() - 1);
            }
        }

        PreviousStatus = _status;
        _status = value;

    }
}      

最后编辑 - 我删除了前面的示例,因为该代码中不存在问题。

事实证明它在应用程序的不同部分,而且很难找到递归的一部分。巧合的是,在linq查询的时候出现了stack overflow错误,导致被递归调用了420000+次。

下面的所有答案都很有帮助,并且是在多线程应用程序中找到问题的正确途径,但是第一个答案明确强调递归是问题所在(尽管它不是问题之一)属性访问器似乎很明显)。

再次感谢

谢谢

最佳答案

检查 ChangeLogProcess 类的属性以确保它不是自引用的。我认为,在这种情况下,这是最有可能导致堆栈溢出异常的原因。

例如:

 private ChangeLogStatus status;
 public ChangeLogStatus Status
 {
      get { return this.Status; }  // instead of this.status
      set { this.status = value }
 }

另一种可能的替代方法是对状态进行相等性检查。您是否为 ChangeLogStatus 覆盖了 Equals()?检查那里以确保您没有任何自引用代码(或者至少没有终止递归的方法)。

关于c# - 在字典的 linq 迭代过程中,什么可能导致堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2252894/

相关文章:

c# - 改进 Linq-XML 到对象查询

java - Web应用程序中的多线程

c# - Linq加入两个相似的对象列表?

c# - 具有C#DirectoryEntry类的多个LDAP连接器

java - 锁定虚拟机内单个线程的文件

c# - AForge 和 OpenCV 的区别

c# - DataBinding 与 entityframework 错误

c# - WPF 绑定(bind)到子集合

c# - 使用 RedisSessionStateProvider 时出现 Microsoft.Owin.Security.AuthenticationTicket SerializationException

c# - MonoDevelop 3.1.1 找不到 System.Xml.Linq