我遇到了一种情况,根据minidump,某些文件在递归下降解析器中导致堆栈溢出。不幸的是,我无法得到一个文件的例子,为了重现这个问题(客户端存在保密问题),这使得我在诊断当前真正的问题时有点困难。如何防止或恢复工作线程上的堆栈溢出?
显然,解析器需要一些注意,但现在我的首要任务就是保持程序运行。作为一项权宜之计,我能做些什么来阻止整个计划的实施?
我的第一选择是找到某种方式来预测我在堆栈中的空间不足,以便在发生溢出之前正常中止解析器。未能解析文件是可以接受的选项。第二种选择是让它发生,捕捉错误并记录下来,然后继续处理其余的数据。
解析发生在Parallel.ForEach()
循环中。如果这有帮助,我愿意将其换为其他方法。
编辑:如果我能得到当前线程堆栈的大小和堆栈指针的位置,真正的杀手是什么。这可能吗?
编辑2:我终于设法拧出某人的样本文件并在调试器中捕获错误。事实证明,这不是属于我们的代码 - 例外发生在HtmlAgilityPack的某处。所以看起来我将不得不尝试找到完全不同的方法。
不知道这是否会有帮助,因为究竟导致堆栈溢出的原因并不清楚(并发性不应该导致这种情况:递归可能),但是您是否尝试过使用ParallelOptions.MaxDegreeOfParallelism来限制并发调用的数量? – Jcl 2012-08-02 19:11:42
一种选择是跟踪解析的当前“深度”,如果它太高,则保释。 – dlev 2012-08-02 19:13:33
@dlev虽然我想了解更多细节。 .NET文档表明,但如何选择合适的最大深度,因为堆栈框架和调用堆栈整体可以具有不同的大小? – 2012-08-02 19:15:19