2010-10-06 3 views
4

Если у меня есть метод, который я знаю, может потенциально рекурсивный бесконечно, но я не могу достоверно предсказать, какие условия/параметры будут вызывать это, что это хороший способ в C# делать это:Какой хороший общий способ поймать исключение StackOverflow в C#?

try 
{ 
    PotentiallyInfiniteRecursiveMethod(); 
} 
catch (StackOverflowException) 
{ 
    // Handle gracefully. 
} 

Очевидно, что в main thread вы не можете этого сделать, но мне сказали несколько раз, что это можно сделать с помощью потоков или AppDomain, но я никогда не видел рабочего примера. Кто-нибудь знает, как это делается надежно?

+0

Вы можете перестроить свой алгоритм? –

+0

Это не обязательно мой алгоритм; например, метод Transform на объекте «XslCompiledTransform» будет разбит, если XSLT имеет в нем рекурсивный шаблон. – Flynn1179

+0

Можете ли вы исправить XSLT? – Arcturus

ответ

11

Вы не можете. От MSDN

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

+0

Собственно, из этого фрагмента я предполагаю, что вы МОЖЕТЕ; в нем конкретно говорится, что процесс будет продолжаться, если домен приложения, в котором произошло исключение, будет выгружен. Это означает, что можно запустить метод в своем собственном домене приложения; мой вопрос: как это можно сделать? – Flynn1179

+0

Эта ссылка может оказаться полезной: http://msdn.microsoft.com/en-us/library/dd380850.aspx. В нем описано, как загрузить новые домены приложений. Возможно, это может быть самая изящная идея. Но хостинг совершенно нового AppDomain кажется немного переборщим. Можете ли вы проверить XSLT на круглые ссылки? – Arcturus

+0

Это не тривиально, но это не главное. Я ищу общее решение, независимо от того, что вызывает переполнение стека. – Flynn1179

1

Там нет никакого способа, чтобы поймать StackOverflowException, но вы можете сделать что-то с необработанным исключением:

static void Main() 
{ 
AppDomain.CurrentDomain.UnhandledException += 
    new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
} 

static void CurrentDomain_UnhandledException 
    (object sender, UnhandledExceptionEventArgs e) 
{ 
    try 
    { 
    Exception ex = (Exception)e.ExceptionObject; 

    MessageBox.Show("Whoops! Please contact the developers with the following" 
      + " information:\n\n" + ex.Message + ex.StackTrace, 
      "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
    } 
    finally 
    { 
    Application.Exit(); 
    } 
} 
+0

Это не срабатывает при исключении StackOverflow, я пробовал, по крайней мере, не из AppDomain.CurrentDomain. – Flynn1179

Смежные вопросы