StackOverflowException в .NET

Попытка разобрать html с регулярным выражением - это не очень хорошая идея. См. этот пост . Используйте настоящий html-парсер, например HtmlAgilityPack .

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(content);
foreach (var a in doc.DocumentNode.Descendants("a"))
{
    a.Attributes["href"].Value = "http://a.com?url=" + HttpUtility.UrlEncode(a.Attributes["href"].Value);
}

var newContent = doc.DocumentNode.OuterHtml;

13
задан Peter Mortensen 5 August 2010 в 00:14
поделиться

4 ответа

Едва ли; переполнение стека, или из исключения памяти происходит в самом CLR, означает, что что-то пошло критически неправильно (я обычно получаю его, когда я был тупицей и создал рекурсивное свойство).

, Когда это состояние происходит, нет никакого пути к CLR для выделения новых вызовов функции или памяти, чтобы позволить ему звонить в обработчики исключений; это, "мы должны остановиться теперь " сценарий.

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

18
ответ дан blowdart 5 August 2010 в 00:14
поделиться

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

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

1
ответ дан Fire Lancer 5 August 2010 в 00:14
поделиться

Существует три вида так называемых "асинхронных исключений". Это - ThreadAbortException, OutOfMemoryException и упомянутый StackOverflowException. Тем excepions позволяют произойти в любой инструкции в Вашем коде.

И, существует также способ преодолеть их:

самым легким является ThreadAbortException. Когда текущий код выполняется в наконец-блоке. ThreadAbortExceptions отчасти "перемещены" до конца наконец-блока. Таким образом, все в наконец-блоке не может быть прервано ThreadAbortException.

Во избежание OutOfMemoryException у Вас есть только одна возможность: ничего не выделяйте на "куче". Это означает, что Нельзя создать новые ссылочные типы.

Для преодоления StackOverflowException Вы нуждаетесь в некоторой помощи от Платформы. Эта справка проявляет в Принужденных регионах Выполнения. Необходимый стек выделяется прежде , фактический код выполнен и дополнительно также гарантирует, что код уже Скомпилирован в JIT и для этого доступен для выполнения.

существует три формы для выполнения кода в Принужденных регионах Выполнения (скопированный с Блог Команды BCL):

  • ExecuteCodeWithGuaranteedCleanup, переполнение стека безопасная форма попытки/наконец.
  • А пробуют/наконец блок, которому предшествует сразу вызов к RuntimeHelpers. PrepareConstrainedRegions. Блок попытки не ограничивается, но вся выгода, наконец, и блоки отказа для той попытки.
  • Как критический финализатор - любой подкласс CriticalFinalizerObject имеет финализатор, который нетерпеливо подготовлен, прежде чем экземпляр объекта выделяется.
    • особый случай А является методом ReleaseHandle SafeHandle, виртуальным методом, который нетерпеливо подготовлен, прежде чем подкласс выделят и назовут от критического финализатора SafeHandle.

можно найти больше в этих сообщениях в блоге:

Принужденные регионы Выполнения и другие опечатки [Brian Grunkemeyer] в Блоге Команды BCL.

Блог Joe Duffy [приблизительно 112] Атомарность и асинхронные отказы исключения , где он дает очень хороший обзор по асинхронным исключениям и устойчивости в .net Платформе.

25
ответ дан Thomas Danecker 5 August 2010 в 00:14
поделиться

blowdart прибил его, выше. Тупое рекурсивное свойство, как он любит это называть. На самом деле это просто проблема слишком быстрого набора кода.

private Thing _myThing = null;

Public Thing MyThing
{
   get{
        return this.MyThing;}
   set{
        this.MyThing = value;}
}
1
ответ дан 1 December 2019 в 17:55
поделиться
Другие вопросы по тегам:

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