Пожалуйста, обратитесь к , выпуск № 2665 , «версия с этим методом еще не опубликована на npm, используйте версию git».
То, сколько раз Вы будете в состоянии рекурсивно вызвать, будет зависеть от:
Guid
, локальные переменные будут взятием больше стека, чем метод, который не имеет никаких локальных переменных, например) , Как избежать переполнений стека? Не рекурсивно вызывайте слишком далеко:), Если Вы не можете быть довольно уверены, что Ваша рекурсия завершится, не идя очень далеко (я был бы взволнован в "больше чем 10", хотя это очень безопасно) тогда переписывают его для предотвращения рекурсии.
Это действительно зависит, на каком рекурсивном алгоритме Вы используете. Если это - простая рекурсия, можно сделать что-то вроде этого:
public int CalculateSomethingRecursively(int someNumber)
{
return doSomethingRecursively(someNumber, 0);
}
private int doSomethingRecursively(int someNumber, int level)
{
if (level >= MAX_LEVEL || !shouldKeepCalculating(someNumber))
return someNumber;
return doSomethingRecursively(someNumber, level + 1);
}
стоит отметить, что этот подход действительно только полезен, где уровень рекурсии может быть определен как логический предел. В случае, что это не может произойти (такие как деление и завоевать алгоритм), необходимо будет решить, как Вы хотите сбалансировать простоту по сравнению с производительностью по сравнению с ограничениями ресурса. В этих случаях Вам, вероятно, придется переключиться между методами, как только Вы поражаете arbritrary предопределенный предел. Эффективное средство выполнения этого, что я использовал в quicksort алгоритме, должно сделать это как отношение общего размера списка. В этом случае логический предел является результатом того, когда условия больше не оптимальны.
Я не знаю ни о каком твердый набор для предотвращения stackoverflows. Я лично пытаюсь удостовериться -
1. Я имею свое основное право случаев.
2. Код достигает основного случая в какой-то момент.
Если Вы генерируете, что много стековых фреймов, Вы могли бы хотеть рассмотреть разворачивание Вашей рекурсии в цикл.
Особенно при выполнении нескольких уровней рекурсии (A-> B-> C-> A-> B...) Вы могли бы найти, что можно извлечь один из тех уровней в цикл и сохранить себя некоторая память.
Нормальный предел, если не много оставляют на стеке между последовательными вызовами, является приблизительно 15000-25000 уровнями глубоко. 25% из этого, если Вы находитесь на IIS 6 +.
Большая часть рекурсивного algorhitms может быть выражена многократно.
существует различный способ увеличить выделенное стековое пространство, но я скорее позволю Вам найти повторяющуюся версию сначала.:)
Кроме наличия разумного размера стека и проверки Вы делите и завоевываете свою проблему, таким образом, что Вы постоянно работаете над меньшей проблемой, не действительно.
Я просто думал о хвостовой рекурсии, но это сложилось, это, C# не поддерживает его. Однако Платформа.NET, кажется, поддерживает его:
http://blogs.msdn.com/abhinaba/archive/2007/07/27/tail-recursion-on-net.aspx
Размер стека по умолчанию для потока составляет 1 МБ, если Вы работаете под CLR по умолчанию. Однако другие хосты могут изменить это. Например, хост ASP изменяет значение по умолчанию на 256 КБ. Это означает, что у Вас может быть код, который работает отлично в соответствии с VS, но повреждается, когда Вы развертываете его на реальной среде хостинга.
, К счастью, можно определить размер стека при создании нового потока при помощи корректного конструктора. По моему опыту, это редко необходимо, но я видел один случай, где это было решением.
можно отредактировать заголовок PE самого двоичного файла для изменения размера по умолчанию. Это полезно, если Вы хотите изменить размер для основного потока. Иначе я рекомендовал бы использовать соответствующего конструктора при создании потоков.
Помните, если необходимо спросить о системных пределах, тогда Вы, вероятно, делаете что-то ужасно неправильно.
Так, если Вы думаете, что могли бы получить переполнение стека в нормальном функционировании тогда, необходимо думать о другом подходе к проблеме.
не трудно преобразовать рекурсивную функцию в повторяющуюся, тем более, что C# имеет Дженерик:: набор Стека. Используя Стек тип перемещает память, используемую в "кучу" программы вместо стека. Это дает Вам диапазон полного адреса, чтобы хранить рекурсивные данные. Если это не достаточно, не слишком трудно разбить на страницы данные к диску. Но я серьезно рассмотрел бы другие решения, если Вы доходите до этой стадии.