用递归替换while循环

时间:2019-02-19 15:06:38

标签: c# sockets recursion while-loop tcpclient

快速简单的问题:

这是:

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);
        }
    }
}

虽然第二个看起来“干净”,但我还是很好奇第一个是否也可以接受-如果不可以,那为什么不呢?

2 个答案:

答案 0 :(得分:6)

在这种情况下,递归是不好的,因为如果程序运行时间过长并且重试了连接,最终将遇到StackOverflowException。

答案 1 :(得分:1)

为什么递归不好?

您将需要了解什么是调用堆栈。

这是在内存中保留的堆栈。每次调用新方法时,都会在该堆栈中添加该方法的引用和参数。该堆栈将保留在内存(RAM)中。

通过递归,如果您继续在没有任何边界条件的情况下调用方法,则堆栈将继续增长。

一段时间后,由于没有足够的内存来容纳它,因此它将无法接受任何其他条目。

那是您将收到“堆栈溢出异常”的时间。

我们可以在不使用递归的情况下重写每个递归算法吗?

可以。这种方法通常称为“迭代方法”。

在每种情况下,您都可以使用辅助堆栈/列表/变量组-保存递归中使用的参数。

然后,您可以遍历这些变量,直到达到边界条件。

这样,您可以实现相同的结果,而无需一次又一次地调用方法。 总是最好使用这种方法。

那为什么人们编写递归算法?

有时候,递归算法非常容易阅读。迭代方法代码可能不容易阅读,这就是为什么人们尝试多次编写递归代码的原因。

您可以基于两件事来决定使用迭代方法还是递归方法:

  • 输入样本

  • 代码可维护性

如果您仍然想编写递归方法,请不要忘记添加边界条件,之后将停止递归。

例如如果您编写递归算法,则树遍历代码(前顺序,顺序,后顺序)更容易理解。 只要您对树中的节点/级别数有所限制,此方法就可以正常工作。如果您已经知道自己的树很大,那么您可能会寻求迭代方式。

希望这可以帮助您更好地了解这些方法。