StackOverflowException没有递归或无限循环?

gni*_*rts 8 c# stack-overflow recursion datagridview

背景

我有一个DataGridView控件正在使用,我在下面添加了我的处理程序,DataGridView.CellFormatting因此某些单元格中的值可以更易于阅读.这个事件处理程序一直很好,格式化所有值没有问题.

然而,最近我发现了一个非常罕见的情况导致一个不寻常的错误.我DataGridView在该项目的截止日期中的列始终具有int值.0表示事件永远不会到期,任何其他值都是截止日期的UTC时间戳.相应的MySQL db列不允许空值.当用户从DataGridView具有截止日期的一行移动到具有截止日期的另一DataGridView行时(此时一切仍然显示正常),然后按下一个按钮从数据库重新加载数据(不发送更新,基本上调用DataAdapter.Fill()),程序生成StackOverflowException**.

没有递归?

对我来说很不寻常的是,我没有看到递归或infinte-looping的位置.我添加了int cellFormatCallCount作为类成员,并在每次调用期间递增它,但是在抛出异常时,调试器将其值显示int为1,这是我所期望的,因为我没有在印象和递归之间发生.

有人能帮助我吗?

如何查看堆栈跟踪?在VS2008中它说: {Cannot evaluate expression because the current thread is in a stack overflow state.}

最好的祝福,

罗宾逊

private int cellFormatCallCount = 0;
private void myDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)  {
    try {
        // to format the cell, we will need to know its value and which column its in
        string value = "";
        string column = "";

        // the event is sometimes called where the value property is null
        if (e.Value != null) {
            cellFormatCallCount++; // here is my test for recursion, this class member will increment each call

            // This is the line that throws the StackOverflowException
            /* ********************* */
            value = e.Value.ToString();
            /* ********************* */

            column = actionsDataGridView.Columns[e.ColumnIndex].Name;
        } else {
            return; // null values cannont be formatted, so return
        }

        if (column == "id") {
            // different code for formatting each column
        } else if (column == "title") {
            // ...
        } else {
            // ...
        }
    } finally {
        cellFormatCallCount = 0; // after we are done with the formatting, reset our recursion counter
    }
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*man 5

显然e.Value.ToString()再次调用CellFormatting事件.这似乎有点合乎逻辑.使用调试器找出它应该很容易.

但实际的递归可能会在其他地方引起,就像你省略的每列格式一样.

您的递归检查不可靠,因为Value == null也会重置它,并且它似乎由所有列共享.使它更紧密地环绕e.Value.ToString():

if (e.Value != null) 
{
   cellFormatCallCount++; 
   System.Diagnostics.Debug.Assert(cellFormatCallCount <= 1, "Recursion");
   value = e.Value.ToString();
   cellFormatCallCount--; 
   ...
} 
Run Code Online (Sandbox Code Playgroud)