如何防止和/或处理 StackOverflowException? [英] How do I prevent and/or handle a StackOverflowException?

查看:35
本文介绍了如何防止和/或处理 StackOverflowException?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想防止或处理 StackOverflowException,这是我从 Xsl 编辑器XslCompiledTransform.Transform 方法得到的> 我在写.问题似乎在于用户可以编写一个无限递归的 Xsl 脚本,并且它只会在调用 Transform 方法时崩溃.(也就是说,问题不仅仅是典型的程序错误,这通常是导致此类异常的原因.)

I would like to either prevent or handle a StackOverflowException that I am getting from a call to the XslCompiledTransform.Transform method within an Xsl Editor I am writing. The problem seems to be that the user can write an Xsl script that is infinitely recursive, and it just blows up on the call to the Transform method. (That is, the problem is not just the typical programmatic error, which is usually the cause of such an exception.)

有没有办法检测和/或限制允许的递归次数?或者有什么其他想法可以防止这段代码对我产生影响?

Is there a way to detect and/or limit how many recursions are allowed? Or any other ideas to keep this code from just blowing up on me?

推荐答案

来自微软:

从 .NET Framework 开始2.0 版,一个 StackOverflowException对象不能被 try-catch 捕获块和相应的过程是默认终止.最后,建议用户编写他们的代码检测和防止堆栈溢出.例如,如果您的应用程序依赖于递归,使用计数器或状态条件终止递归循环.

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.

我假设异常发生在内部 .NET 方法中,而不是在您的代码中.

I'm assuming the exception is happening within an internal .NET method, and not in your code.

你可以做几件事.

  • 编写代码来检查 xsl 是否存在无限递归并在应用转换之前通知用户(呃).
  • 将 XslTransform 代码加载到单独的进程中(Hacky,但工作量较少).

您可以使用 Process 类加载将应用转换到单独进程的程序集,并在它终止时提醒用户失败,而不会终止您的主应用程序.

You can use the Process class to load the assembly that will apply the transform into a separate process, and alert the user of the failure if it dies, without killing your main app.

我刚刚测试过,这是如何做到的:

I just tested, here is how to do it:

主进程:

// This is just an example, obviously you'll want to pass args to this.
Process p1 = new Process();
p1.StartInfo.FileName = "ApplyTransform.exe";
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

p1.Start();
p1.WaitForExit();

if (p1.ExitCode == 1)    
   Console.WriteLine("StackOverflow was thrown");

应用转换过程:

class Program
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
        throw new StackOverflowException();
    }

    // We trap this, we can't save the process, 
    // but we can prevent the "ILLEGAL OPERATION" window 
    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.IsTerminating)
        {
            Environment.Exit(1);
        }
    }
}

这篇关于如何防止和/或处理 StackOverflowException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆