我的服务器出现StackOverflowException
。它有超过 20,000 行代码,我找不到它被抛出的位置...因为 try/catch 不起作用,我无法获取错误...有什么方法可以获取错误日志吗? UnhandledExceptionEventHandler
没有记录它,所以...我怎样才能在它使我的服务器崩溃之前检测到它并记录错误?您也可以建议我如何找到 StackOverflowException
:)
我使用的是 .NET Framework 4.5
UnhandledExceptionEventHandler代码:
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(Program.UnhandledExceptionEventArgs);
private static void UnhandledExceptionEventArgs(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
Console.WriteLine(ex.ToString());
}
图片:
最佳答案
一般来说,你不能。 StackOverflowException
是您无法捕获的少数异常之一。
如果异常发生在您自己的代码中,最好的解决方案是将您的算法从递归调用转换为使用堆分配的 Stack<T>
的算法跟踪深度状态,并且还允许您捕获堆栈容量超过阈值的情况( if( stack.Count >= 4000 ) break;
。
enum Result {
Found,
NotFound,
Aborted
}
public static Result DepthFirstSearch(Node node) {
Stack<Node> stack = new Stack<Node>();
stack.Push( node );
while( stack.Count > 0 ) {
Node n = stack.Pop();
if( IsNodeWeWant( n ) ) return Result.Found;
foreach(Node child in n.Children) stack.Push( child );
if( stack.Count >= 4000 ) return Result.Aborted;
}
return Result.NotFound;
}
如果您觉得必须使用递归调用,请向您的方法添加一个名为“深度”的附加整数参数(每次递归调用都会增加)。在你的函数中,你可以检查你的深度,并在出现堆栈溢出之前中断。
示例:
enum Result {
Found,
NotFound,
Aborted
}
public static Result DepthFirstSearch(Node node, Int32 depth) {
if( depth >= 4000 ) return Result.Aborted;
if( IsNodeWeWant( node ) ) return Result.Found;
foreach(Node child in node.Children) {
Result result = DepthFirstSearch( child, depth + 1 );
if( result != Result.NotFound ) return result; // return Found or Aborted
}
}
但是,如果异常发生在代码之外(并且您无法在输入数据之前验证数据以中止操作),那么您唯一的选择就是创建一个托管有错误代码的子进程。您可以使用某种形式的 IPC 或共享内存进行通信(尽管您不能直接共享 POCO,至少在没有序列化的情况下不能)。
关于c# - 如何在 StackOverflowException 捕获之前检测并记录错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22082794/