快速简单的问题:
这是:
private static void SetupConnection()
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
SetupConnection();
}
可行的替代方案:
private static void SetupConnection()
{
while (true)
{
try
{
TcpClient client = new TcpClient(myServer, myPort);
//Do whatever...
break;
}
catch (SocketException)
{
//Server is closed. Retry in 10 minutes.
Thread.Sleep(600000);
}
}
}
虽然第二个看起来“干净”,但我还是很好奇第一个是否也可以接受-如果不可以,那为什么不呢?
答案 0 :(得分:6)
在这种情况下,递归是不好的,因为如果程序运行时间过长并且重试了连接,最终将遇到StackOverflowException。
答案 1 :(得分:1)
为什么递归不好?
您将需要了解什么是调用堆栈。
这是在内存中保留的堆栈。每次调用新方法时,都会在该堆栈中添加该方法的引用和参数。该堆栈将保留在内存(RAM)中。
通过递归,如果您继续在没有任何边界条件的情况下调用方法,则堆栈将继续增长。
一段时间后,由于没有足够的内存来容纳它,因此它将无法接受任何其他条目。
那是您将收到“堆栈溢出异常”的时间。
我们可以在不使用递归的情况下重写每个递归算法吗?
可以。这种方法通常称为“迭代方法”。
在每种情况下,您都可以使用辅助堆栈/列表/变量组-保存递归中使用的参数。
然后,您可以遍历这些变量,直到达到边界条件。
这样,您可以实现相同的结果,而无需一次又一次地调用方法。 总是最好使用这种方法。
那为什么人们编写递归算法?
有时候,递归算法非常容易阅读。迭代方法代码可能不容易阅读,这就是为什么人们尝试多次编写递归代码的原因。
您可以基于两件事来决定使用迭代方法还是递归方法:
输入样本
代码可维护性
如果您仍然想编写递归方法,请不要忘记添加边界条件,之后将停止递归。
例如如果您编写递归算法,则树遍历代码(前顺序,顺序,后顺序)更容易理解。 只要您对树中的节点/级别数有所限制,此方法就可以正常工作。如果您已经知道自己的树很大,那么您可能会寻求迭代方式。
希望这可以帮助您更好地了解这些方法。