在 C# 中捕获 StackOverflow 异常的通用方法是什么?

发布于 2024-09-26 03:46:01 字数 287 浏览 6 评论 0原文

如果我有一个我知道可能无限递归的方法,但我无法可靠地预测什么条件/参数会导致它,那么在 C# 中执行此操作的好方法是什么:

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

显然在主线程中你不能执行此操作,但我曾多次被告知可以使用线程或 AppDomain 来完成此操作,但我从未见过有效的示例。有人知道这是如何可靠地完成的吗?

If I have a method that I know could potentially recurse infinitely, but I can't reliably predict what conditions/parameters would cause it, what's a good way in C# of doing this:

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

Obviously in the main thread you can't do this, but I've been told a few times it's possible to do it using threads or AppDomain's, but I've never seen a working example. Anybody know how this is done reliably?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蛮可爱 2024-10-03 03:46:01

你不能。来自 MSDN

从 .NET Framework 开始
2.0 版,StackOverflowException
try-catch 无法捕获对象
块,对应的进程是
默认终止。最后,
建议用户编写代码
检测并防止堆栈
溢出。例如,如果您的
应用程序取决于递归,使用
计数器或状态条件
终止递归循环。笔记
托管的应用程序
公共语言运行时 (CLR) 可以
指定 CLR 卸载
堆栈所在的应用程序域
发生溢出异常并让
相应的过程继续进行。为了
更多信息,请参见
ICLRPolicyManager 接口和
托管概述。

You can't. From MSDN

Starting with the .NET Framework
version 2.0, a StackOverflowException
object cannot be caught by a try-catch
block and the corresponding process is
terminated by default. Consequently,
users are advised to write their code
to detect and prevent a stack
overflow. For example, if your
application depends on recursion, use
a counter or a state condition to
terminate the recursive loop. Note
that an application that hosts the
common language runtime (CLR) can
specify that the CLR unload the
application domain where the stack
overflow exception occurs and let the
corresponding process continue. For
more information, see
ICLRPolicyManager Interface and
Hosting Overview.

她说她爱他 2024-10-03 03:46:01

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

There is no way to catch StackOverflowException, but you can do something with unhandled exception:

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();
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文