StackOverflowException без цикла рекурсии или бесконечного цикла?

Потому что этот метод рендеринга - static. По определению методы static не могут получить доступ к переменной экземпляра. Вы должны удалить этот модификатор, если это возможно, и он должен работать.

8
задан gnirts 22 April 2009 в 20:21
поделиться

6 ответов

По-видимому, 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--; 
   ...
} 
5
ответ дан 5 December 2019 в 17:41
поделиться

Учитывая, что это событие, может ли оно вызывать себя?

1
ответ дан 5 December 2019 в 17:41
поделиться

Полностью случайное предположение (без трассировки стека это все, что я могу сделать) ...

Вы пытаетесь отобразить / отформатировать тип, который имеет потенциально рекурсивный ToString () ?

public string ToString()
{
   return ... this.ToString() ...
   // or
   return String.Format("The value is {0}", this);
}

Опечатка / ошибка, подобная этой, может вызвать StackOverflowException ...

2
ответ дан 5 December 2019 в 17:41
поделиться

Это не связано с проблемой, но на самом деле вы можете иметь StackOverflowException вообще без рекурсии только с:

throw new StackOverflowException();
0
ответ дан 5 December 2019 в 17:41
поделиться

@Daniel: Если бы это было проблемой, разве это не вызвало бы исключение в строке:

if (e.Value != null) {

@gnirts: Не могли бы вы опубликовать полный метод и трассировку стека?

@BCS (ниже): Я думаю, что это может быть, но это может быть легко в некотором коде, который не показан в опубликованном демо.

PS. Извините, это должен был быть комментарий, но у меня недостаточно повторений :-D

1
ответ дан 5 December 2019 в 17:41
поделиться

Попробуйте сделать статическую переменную cellFormatCallCount, чтобы она использовалась всеми экземплярами класса. Я подозреваю, что событие как-то срабатывает само по себе, но вы его не видите, потому что cellFormatCallCount является локальным для каждого экземпляра класса, обрабатывающего событие, и, следовательно, никогда не увеличивается на единицу больше 1. Если это так, то фактический триггер для стекового потока (рекурсия) может быть где угодно в методе, и в этой строке просто не хватает места в стеке.

После того, как вы сделали переменную статической, вы можете вызвать исключение, когда оно превышает определенное (маленькое) значение, как 2. Это исключение должно оставить видимую трассировку стека.

1
ответ дан 5 December 2019 в 17:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: