没有无限循环的堆栈溢出异常(据我所知)
本文关键字:异常 据我所知 栈溢出 堆栈 无限循环 | 更新日期: 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,但据我所知,它只适用于堆。有没有类似的工具可以用于我的程序正在运行的堆栈?
我发现这篇文章是关于两个名为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();
}
}
最终编辑
好的,所以元骑士的回答告诉我,我确实有一个无限循环。我有一个事件处理程序订阅了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和set
ter的情况下谈论Amount
的方法。