C# ловят исключение из-за переполнения стека

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

Исключение из-за переполнения стека ведет себя специальным способом? Я могу ловить/обрабатывать исключение правильно?

Не уверенный при необходимости, но дополнительная информация:

  • исключение не выдается в основном потоке

  • объект, где код выдает исключение, вручную загружается блоком. LoadFrom (...).CreateInstance (...)

110
задан theduck 28 October 2019 в 17:38
поделиться

7 ответов

Начиная с версии 2.0 исключение StackOverflow может быть обнаружено только в следующих обстоятельствах.

  1. CLR выполняется в размещенной среде * , где хост специально позволяет Обрабатываемые исключения StackOverflow
  2. Исключение stackoverflow вызывается кодом пользователя, а не фактической ситуацией переполнения стека ( Ссылка )

* «размещенная среда» как в «мой код размещает CLR, и я настраиваю параметры CLR ", а не" мой код работает на общем хостинге "

104
ответ дан 24 November 2019 в 03:12
поделиться

As several users have already said, you can't catch the exception. However, if you're struggling to find out where it's happening, you may want to configure visual studio to break when it's thrown.

To do that, you need to open Exception Settings from the 'Debug' menu. In older versions of Visual Studio, this is at 'Debug' - 'Exceptions'; in newer versions, it's at 'Debug' - 'Windows' - 'Exception Settings'.

Once you have the settings open, expand 'Common Language Runtime Exceptions', expand 'System', scroll down and check 'System.StackOverflowException'. Then you can look at the call stack and look for the repeating pattern of calls. That should give you an idea of where to look to fix the code that's causing the stack overflow.

21
ответ дан 24 November 2019 в 03:12
поделиться

Правильный способ - исправить переполнение, но ....

Вы можете увеличить стек: -

using System.Threading;
Thread T = new Thread(threadDelegate, stackSizeInBytes);
T.Start();

Вы можете использовать свойство System.Diagnostics.StackTrace FrameCount для подсчитайте использованные вами кадры и создайте собственное исключение при достижении предела кадров.

Или вы можете рассчитать размер оставшегося стека и выдать собственное исключение, когда оно упадет ниже порогового значения: поймать сыр. ;)

46
ответ дан 24 November 2019 в 03:12
поделиться

Со страницы MSDN на StackOverflowException s:

В предыдущих версиях .NET Framework, ваше приложение может поймать объект StackOverflowException (например, чтобы восстановить неограниченная рекурсия). Однако это практика в настоящее время не рекомендуется потому что значительный дополнительный код требуется для надежного захвата стопки исключение переполнения и продолжить выполнение программы.

Начиная с .NET Framework версия 2.0, исключение StackOverflowException объект не может быть пойман попыткой блок и соответствующий процесс прекращено по умолчанию. Как следствие, пользователям рекомендуется писать свой код обнаруживать и предотвращать стек переполнение. Например, если ваш приложение зависит от рекурсии, используйте счетчик или состояние состояния для завершить рекурсивный цикл. Запись что приложение, в котором размещается общеязыковая среда выполнения (CLR) может укажите, что CLR выгружает домен приложения, где находится стек возникает исключение переполнения, и пусть соответствующий процесс продолжается. За подробнее см. Интерфейс ICLRPolicyManager и Размещение общеязыковой среды выполнения.

38
ответ дан 24 November 2019 в 03:12
поделиться

Да из CLR 2.0 переполнение стека считается неустранимой ситуацией. Таким образом, среда выполнения все еще завершает процесс.

Подробности см. В документации http://msdn.microsoft.com/en-us/library/system.stackoverflowexception.aspx

6
ответ дан 24 November 2019 в 03:12
поделиться

Вы не можете. CLR вам не позволит. Переполнение стека является фатальной ошибкой и не может быть исправлено.

5
ответ дан 24 November 2019 в 03:12
поделиться

Это невозможно, и по уважительной причине (например, подумайте обо всех этих уловках (Исключение) {}).

Если вы хотите продолжить выполнение после переполнения стека, запустите опасный код в другом домене приложений. Политики CLR могут быть настроены так, чтобы завершать текущий домен приложений при переполнении, не затрагивая исходный домен.

3
ответ дан 24 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

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