【问题标题】:System.StackOverflowException That makes no sense... how to debug? [closed]System.StackOverflowException 这毫无意义……如何调试? [关闭]
【发布时间】:2014-01-16 20:22:21
【问题描述】:

我正在构建一个使用简单 MVVM 架构和 EF 的 WPF 应用程序。

我看到一个奇怪的问题,如果我尝试设置日期时间属性,我会得到一个System.StackOverflowException。如果我不设置 datetime 属性,我不会得到异常。

绑定:

   <DatePicker Style="{StaticResource Dp}" 
               Grid.Column="1" 
               SelectedDate="{Binding Date, UpdateSourceTrigger=PropertyChanged}" />

公共财产:

public DateTime Date
{
    get
    {
        return _criticalDate.Date;
    }
    set
    {
        if (_criticalDate != null && value != null && _criticalDate.Date == value)
            return;
        _criticalDate.Date = value;
        OnPropertyChanged("Date");
    }
}

尝试使用调试器单步执行似乎行不通。我已经查看了所有内容,试图了解发生了什么......关于可能导致这种情况的任何提示?

这是CriticalDate 类的定义,

public partial class CriticalDate
{
    public int ID { get; set; }
    public System.DateTime Date { get; set; }
    public string CriticalReason { get; set; }
    public int FileID { get; set; }
}

_criticalDate 字段是CriticalDate 类的私有实例。 CriticalDate 是 EF 从我的 DB 架构中创建的一个类。它本身不是DateTime

最终更新

我仍然不知道出了什么问题...我撕掉了有问题的部分(包括装订)并从头开始重写。不知道我做了什么不同的事情,但现在可以了。我认为这与项目控制的设置方式有关......如果我有更多时间(愚蠢的截止日期),我会回去看看它是什么,但现在它是一个谜。

感谢您分享我的困惑,如果只是这么简单的话。

【问题讨论】:

  • 添加if (_criticalDate == this) throw new Exception("Bug");
  • StackOverflowException 在哪个函数上?顺便说一句,当 _criticalDate 为空时,我希望出现 NullReferenceException ...
  • _criticalDate的类型是什么?你能发布实现吗?
  • 您可能需要在抛出异常后查看堆栈(为此在 DEBUG 上运行应用程序)。方法的名称应该提供一些线索...
  • If I don't set the datetime property, I don't get the exception. - 你在哪里设置??

标签: c#


【解决方案1】:

尝试删除OnPropertyChanged("Date");,或将绑定模式更改为OneWayToSource

来自documentation of UpdateSourceTrigger

TwoWay 或 OneWayToSource 的绑定侦听目标属性中的更改并将它们传播回源。这称为更新源。通常,只要目标属性更改,就会发生这些更新。这适用于复选框和其他简单控件,但通常不适用于文本字段。每次击键后更新可能会降低性能,并且它会剥夺用户在提交新值之前退格和修复打字错误的通常机会。因此,Text 属性的默认 UpdateSourceTrigger 值为 LostFocus 而不是 PropertyChanged。

我认为Date_set方法上的OnPropertyChanged("Date");是在更新UI,这反过来又再次调用Date_set方法,完成循环并引起递归。

【讨论】:

  • 奇怪的是,即使设置器完全为空,我也会收到此错误。没有 OnPropertyChange,没有设置私有属性,但我仍然得到错误。
【解决方案2】:

编辑: 以下是无用的,因为调试器不显示堆栈溢出的调用堆栈。相反,看看How to debug a stackoverflowexception in .NET


将 Visual Studio 调试器设置为在 StackOverflowExceptions 上中断并检查调用堆栈。

Ctrl+Alt+E

Debug->Exceptions...

单击Find 并输入StackOverflow,然后选中Thrown 列中的框。

您可能会在同一个方法或一组方法中进行数百次递归调用。

如果异常发生在库中,您可能需要禁用“仅我的代码”

【讨论】:

  • 看不到有堆栈溢出异常的调用堆栈。您会收到一条可爱的消息,说“无法评估,因为您处于堆栈溢出状态。”这就是为什么我无法弄清楚......不知道发生了什么。
  • @Chronicide Doh,你是对的。我忘记了。看起来还有其他方法可以调试它。 stackoverflow.com/questions/4733878/…
【解决方案3】:

确保在不需要时不更新日期,并打破绑定中的反馈循环。我通常把这个检查放在我的设置器周围:

public DateTime Date
{
    get
    {
        return _criticalDate.Date;
    }
    set
    {
        if (_criticalDate.Date != value)
        {
            if (_criticalDate != null && value != null && _criticalDate.Date == value)
               return;
            _criticalDate.Date = value;
            OnPropertyChanged("Date");
        }
    }
}

【讨论】:

  • 我已经在这样做了...如果日期匹配,则返回,因此如果这样做,onpropertychanged 上的设置将不会运行。和你的建议一样,只是有点倒退。
  • @Chronicide - 嗯,仅供参考 - 如果 _criticalDate == null,你会崩溃,所以检查是额外的。此外,如果 value==null 和 _criticalDate.Date==null,您的检查将不起作用。如果您尝试设置断点会发生什么?
  • 如果valueDateTime 它永远不可能是null
猜你喜欢
  • 2015-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2017-11-17
  • 2011-04-18
相关资源
最近更新 更多