Предотвращение StackOverFlow в рекурсивных функциях - PullRequest
8 голосов
/ 28 января 2011

У меня есть рекурсивная функция в BaseClass, которая полагается на функцию protected virtual в качестве условия возврата.

Возможно, дочерний класс может переопределить эту функцию неправильно и приводит к StackOverFlowисключение.Хуже всего то, что есть некоторые медленные сетевые вызовы, и исключение не произойдет в ближайшее время (многие ресурсы тратятся в течение длительного времени).

Я ищу способ проверки StackOverFlow на ранних стадиях некоторыхпуть в базовом классе (возможно, используя Reflection и текущий уровень рекурсии).

Есть идеи?

Ответы [ 3 ]

9 голосов
/ 28 января 2011

Вы можете передать простое целое число 'глубину' рекурсивной функции и увеличивать его при каждом последующем вызове. Если она становится больше максимально допустимой глубины, бросьте Исключение вправо, вместо того, чтобы ждать, пока не станет слишком поздно и возникло страшное исключение StackOverflow.

Такие механизмы безопасности (счетчик приращений, проверьте, что он не слишком большой) также могут быть полезны в циклах while, где небольшая ошибка может вызвать бесконечный цикл, потребляющий огромное количество ЦП.

В больших системах со многими пользователями (например, веб-сайтами) иногда лучше принять меры предосторожности, подобные этим, с рекурсией и циклами while, поскольку последствия могут выходить далеко за пределы одной веб-страницы или одного пользователя системы. Это не красивый кодекс, и пуристы, без сомнения, будут противиться этому, но он эффективен, он оборонителен и прагматичен.

1 голос
/ 28 января 2011

Решите проблему вместо создания обходного пути. Создайте приватную рекурсивную функцию, которая вызывает защищенную виртуальную функцию.

0 голосов
/ 28 января 2011

Хотя вы, вероятно, можете прочитать стек вызовов и проанализировать его, я бы этого не сделал.

  1. Это замедлит выполнение
  2. Это не ответственность вашего базового класса
  3. Документирование поведения вашего базового класса

Альтернативой может быть анализ стека вызовов только в режиме DEBUG.Вот небольшой код, чтобы узнать, как получить стек вызовов.

using System.Diagnostics;

[STAThread]
public static void Main()
{
  StackTrace stackTrace = new StackTrace();           // get call stack
  StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

  // write call stack method names
  foreach (StackFrame stackFrame in stackFrames)
  {
    Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
  }
}

С этого сайта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...