System.StackOverflowException这没有意义......如何调试?

时间:2014-01-16 20:22:21

标签: c#

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

我看到一个奇怪的问题,如果我尝试设置datetime属性,我得到一个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从我的数据库架构创建的类。它本身不是DateTime

最终更新

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

感谢分享我的困惑,如果只是如此简短。

3 个答案:

答案 0 :(得分:0)

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

来自documentation of UpdateSourceTrigger

  

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

我相信OnPropertyChanged("Date");方法上的Date_set正在更新UI,而UI又会再次调用Date_set方法,从而完成循环并导致递归。

答案 1 :(得分:0)

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


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

Ctrl+Alt+E

Debug->Exceptions...

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

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

如果库内发生异常,您可能需要禁用“Just My Code”

答案 2 :(得分:0)

确保在不需要时不更新日期,并打破绑定中的反馈循环。我通常会在我的二传手周围进行检查:

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