我在一个C#的AI程序中使用递归调用来寻找最佳的下一步棋(使用30×30的数组来存储当前棋盘状态)。每走一步,我都想看看从新的棋盘状态出发,哪些可能的走法是最好的…依此类推,直到我达到“游戏结束”的位置(在该状态下无法再进行移动)或者计时器停止进程且不再进行递归调用(返回已知的“最佳”位置)。这只是为了解释为什么我必须使用递归(这不是尾递归),而且我不能使用单一的(全局)棋盘状态,而必须搜索从当前状态出发的所有可能的棋盘状态。
(有时)我会遇到System.StackOverflowException异常。在进行下一次递归调用之前,有没有办法检查可用的堆栈空间?这样我就可以将当前状态作为“目前找到的最佳位置”返回,而不进行下一次递归调用。即当可用的堆栈空间变得太小时,也应视为基本情况处理。
当然,另一种选择可能是将每个递归调用放在try..catch块中,并通过将其作为基本情况来处理System.StackOverflowException异常?
回答:
如果你真的想走这条路,你可以使用EnsureSufficientExecutionstack
方法。
正如其他人指出的,从.NET 2.0开始,你不能捕获StackOverflowException
异常,然而,从MSDN文档中你知道前述方法具有以下行为:
确保剩余的堆栈空间足够执行平均的.NET Framework函数。
当根据此方法判断堆栈空间不足时,它将抛出一个你可以捕获的InsufficientExecutionStackException
异常。