什么';在C#中捕获StackOverflow异常的一般方法是什么?

什么';在C#中捕获StackOverflow异常的一般方法是什么?,c#,exception-handling,stack-overflow,C#,Exception Handling,Stack Overflow,如果我有一种方法,我知道它可能无限递归,但我不能可靠地预测什么条件/参数会导致它,那么在C#中有什么好方法可以做到这一点: try { PotentiallyInfiniteRecursiveMethod(); } catch (StackOverflowException) { // Handle gracefully. } 很明显,在主线程中你不能这样做,但是我被告知有几次使用线程或AppDomain可以这样做,但我从未见过一个有效的示例。有人知道这是如何可靠地完成的吗?你不能。从

如果我有一种方法,我知道它可能无限递归,但我不能可靠地预测什么条件/参数会导致它,那么在C#中有什么好方法可以做到这一点:

try
{
  PotentiallyInfiniteRecursiveMethod();
}
catch (StackOverflowException)
{
  // Handle gracefully.
}
很明显,在主线程中你不能这样做,但是我被告知有几次使用线程或AppDomain可以这样做,但我从未见过一个有效的示例。有人知道这是如何可靠地完成的吗?

你不能。从

从.NET框架开始 版本2.0,StackOverflowException 对象不能被try-catch捕获 块,相应的进程是 默认终止。因此,, 建议用户编写自己的代码 检测并防止堆栈 溢流例如,如果您的 应用程序依赖于递归,请使用 计数器或状态条件 终止递归循环。注 这是一个承载 公共语言运行库(CLR)可以 指定CLR卸载 堆栈所在的应用程序域 发生溢出异常并让 相应的过程继续。对于 有关详细信息,请参阅 ICLRPolicyManager接口和 托管概述


无法捕获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();
  }
}

你能重新设计你的算法吗?它不一定是我的算法;例如,如果XSLT中包含递归模板,则
xslcomiledtransform
对象上的
Transform
方法将中断。这不一定是我的XSLT,而且这只是一个示例。+1,非常有趣的问题。我的第一个直觉反应是:“这在原则上是不可能的”,但由于异常无论如何都会解开堆栈,因此没有理由不这样做;它特别指出,如果卸载发生异常的应用程序域,进程将继续。这意味着可以在它自己的应用程序域中运行该方法;我的问题是,如何做到这一点?这个链接可能会很有用:。它描述了如何加载新的应用程序域。也许这是最优雅的想法。但是托管一个全新的AppDomain似乎有点过分了。。你能验证XSLT的循环引用吗?这不是小事,但这不是重点;无论是什么原因导致堆栈溢出,我都在寻找一个通用的解决方案。对于更通用的解决方案,我确实认为您需要深入该领域。我认为这不会更容易(我已经尝试过,在StackOverflow异常中不会触发;至少在AppDomain.CurrentDomain中不会。