没有无限循环的堆栈溢出异常(据我所知)

时间:2012-01-25 14:41:18

标签: c# wpf xaml entity-framework-4 stack-overflow

我有一个堆栈溢出错误,我很确定我没有任何类型的无限递归(至少我已经盯着错误几个小时了,我无法想象它是如何循环的无限)。

以下是代码:

    public decimal? Amount
    {
        get
        {
            if (!string.IsNullOrEmpty(_savedWork.Amount))
                return decimal.Parse(_savedWork.Amount);
            else
                return null;
        }
        set
        {
            if (value.HasValue)
            {
                _savedWork.Amount = value.Value.ToString();
                Percent = null;
            }
            else
                _savedWork.Amount = "";
            OnPropertyChanged("Amount");
        }
    }

#注意我有一个以可以为空的十进制字符串的字符串,这就是我要转换它的原因。请不要让我说明为什么我这样做。

savedWork.Amount = value.Value.ToString()是我收到错误的地方。

基本上我认为我的堆栈太小(或者我认为我的代码太大了)。 我基本上运行这个代码两次,它在一种形式下工作,但是当我制作另一种形式并将其放在那里时,我不认为这两种形式之间的区别在于倾斜堆栈。 < / p>

有没有办法确定我做错了什么?我想知道代码的哪些部分占用太多或者持续时间太长等等。

我已经对堆栈/堆如何工作以及我对PerfMon.exe的了解做了一些研究,但据我所知它只适用于堆。是否有类似的工具,我可以用于我的程序正在运行的堆栈?

我发现了this post有关2个名为 windbg cdb 的工具,但我找不到有关如何安装/使用它们的更多信息。这些工具是正确的方法吗?

或者,如果存在无限循环或某些事情会很棒。

修改

这里是Amount属性所请求的代码(由EntityFramework自动生成)正如我在评论中所说,步骤甚至没有到达这里。我确实认为我的堆栈限制正在达到。

  public global::System.String Amount
    {
        get
        {
            return _Amount;
        }
        set
        {
            OnAmountChanging(value);
            ReportPropertyChanging("Amount");
            _Amount = StructuralObject.SetValidValue(value, true);
            ReportPropertyChanged("Amount");
            OnAmountChanged();
        }
    }

最终编辑

好的, Meta-Knight 的答案告诉我,我确实有一个无限循环。我有一个事件处理程序订阅了DisplayTypeOfInvestment的PropertyChanged事件(Amount属性所属的类)。处理程序看起来像这样:

 void DisplayTypeOfInvestmentList_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
            _typeOfInvestmentFormSavedWork.TypeOfInvestment.Clear();
            foreach (DisplayInvestmentFund d in _displayInvestmentFundList)
            {
                _typeOfInvestmentFormSavedWork.TypeOfInvestment.Add(d.SavedWork);
            }

            OnPropertyChanged("TypeOfInvestmentFormSavedWork");

    }

TypeOfInvestmentFormSavedWork是一个完全不同的类,其中包含它自己的SavedWork类版本,我们看到它使用的是Amount属性。此方法的目的是在Amount属性更改时将此TypeOfInvestmentFormSavedWork属性更新为_savedWork的新值。由于某种原因,这会触发DisplayTypeOfInvestment viewmodel的PropertyChanged。我没弄明白,但我把方法改成了这样:

 void DisplayTypeOfInvestmentList_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Amount" || e.PropertyName == "Percent")
        {
            _savedWork.TypeOfInvestment.Clear();
            foreach (DisplayInvestmentFund d in _displayInvestmentFundList)
            {
                _savedWork.TypeOfInvestment.Add(d.SavedWork);
            }

            OnPropertyChanged("CurrentWork");
        }
    }

当调用Add方法时,if语句会停止在DisplayInvestmentFund中更改奇怪的属性。

我意识到这个答案没有多大意义,但是对于我来说,详细解释这个问题会花费很长时间 。我也意识到这可能意味着我的代码很糟糕。我不知道该怎么做。谢谢你的帮助。

4 个答案:

答案 0 :(得分:6)

我的猜测是,您在Amount调用的一个事件处理程序中分配给OnPropertyChanged

另一种可能性是您在SavedWork.Amount的设置器中有代码再次调用YourClass.Amount


但你为什么不调试呢?只需单步执行Visual Studio调试器中的代码即可。

堆栈跟踪也应该有用。通过无限递归,您通常会获得重复的方法序列。如果我的猜测是正确的,重复的部分将是:

MyClass.set_Amount
MyClass.OnPropertyChanged
OtherClass.myClass_amount_changed

答案 1 :(得分:2)

与_savedWork相同类型的Amount成员的类是什么?

因为可能有这个循环:

1)您为Amount

指定一个值

2)在设置值之前,为_savedWork.Amount

指定一个值

3)在设置_savedWork.Amount的值之前,再次触发该行

4)在设置_savedWork._savedWork.Amount的值之前......

5)在设置_savedWork._savedWork._savedWork.Amount的值之前...

这无穷无尽。

答案 2 :(得分:1)

必须以某种方式对Amount setter进行递归调用。你可以通过“踩到”属性而不是踩到它来调试它。如果你设置VS使它不进入属性,你仍然可以在你的setter中放置一个断点来模拟“步入”。至于VS没有踩到.edmx文件,正如CodeInChaos所提到的那样,该类可能被标记为DebuggerStepThrough属性。

答案 3 :(得分:0)

_savedWork是与您列出的Amount属性相同类型的对象吗?因为给你一个堆栈溢出错误!在这种情况下,您需要找到一种方式来讨论Amount,而无需调用getset