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

本文关键字:异常 据我所知 栈溢出 堆栈 无限循环 | 更新日期: 2023-09-27 18:21:28

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

这是代码:

    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");
        }
    }

#注意,我有一个字符串位于一个可以为null的十进制中,这就是我转换它的原因。请不要让我去解释我为什么要这么做

线CCD_ 1是我得到错误的地方。

基本上,我认为我的堆栈太小了(或者我想我的代码太大了)我基本上运行了两次这个代码,当它在一个表单中时有效,但当我制作另一个表单并将其放置在那里时无效,所以我认为这两个表单之间的区别在于翻转堆栈

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

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

我发现这篇文章是关于两个名为windbgcdb的工具的,但我找不到太多关于如何安装/使用它们的信息。这些工具是正确的方法吗?

或者,如果有一个无限循环或其他很棒的东西。

编辑

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

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

最终编辑

好的,所以元骑士的回答告诉我,我确实有一个无限循环。我有一个事件处理程序订阅了DisplayTypeOfInvestment(Amount Property所属的类)的PropertyChanged事件。处理程序看起来是这样的:

 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视图模型的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中奇怪的属性的更改。

我意识到这个答案没有多大意义,但对我来说,要详细解释这个问题需要很长时间。我也意识到这可能意味着我的代码不好。我不知道该怎么办。谢谢你们的帮助。

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

我的猜测是,您正在OnPropertyChanged调用的一个事件处理程序中为Amount赋值。

另一种可能性是SavedWork.Amount的setter中有代码,它会再次调用YourClass.Amount


但你为什么不调试一下呢?只需在Visual Studio调试器中逐步完成代码。

堆栈跟踪也应该很有用。使用无休止的递归,通常会得到一系列重复的方法。如果我的猜测是正确的,重复的部分将类似于:

MyClass.set_Amount
MyClass.OnPropertyChanged
OtherClass.myClass_amount_changed

哪个Amount成员的类是否与_savedWork类型相同?

因为可能存在这样的循环:

1) 您为Amount 指定一个值

2) 在设置该值之前,您为_savedWork.Amount 分配一个值

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

4) 在_savedWork的值之前_savedWork。已设置金额。。。

5) 在_savedWork的值之前_savedWork_savedWork。已设置金额。。。

这是无限的和超越。

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

_savedWork是与您列出的Amount属性类型相同的对象吗?因为给您一个堆栈溢出错误!在这种情况下,您需要找到一种在不调用savedWork.Amount = value.Value.ToString()1ter和setter的情况下谈论Amount的方法。