TcpClient上的堆栈溢出(递归)

问题描述 投票:0回答:1

由于重复调用new,如果保持原样,以下代码可能会产生堆栈溢出异常:

async void Connect()
{
    try 
    {
        client = new TcpClient(ip, port);
    }
    catch (Exception e)
    {
        HandleException(e); // Most likely will be a SocketException e.g. connection refused
        Connect(); // Try to connect again
    }
}

尽管我可以例如通过以下方式减少发生这种情况的机会在放弃和退出递归之前添加了最大数量的重试,我宁愿编写它,以便释放内存并且不会发生堆栈溢出异常。

我曾考虑过将其放入while循环中,但我认为这会遇到相同的问题,例如

while (!connected)
{
    try
    {
        client = new TcpClient(ip, port);
        connected = true;
    }
    catch (Exception e)
    {
        HandleException(e);
    }
}

除了具有任意定义的最大重试次数之外,还有更好的方法来避免堆栈溢出异常吗?

.net recursion stack-overflow tcpclient
1个回答
0
投票

[我认为,如果我们优雅地关闭套接字(通过添加SocketException),那么无论递归方法调用Connect()多少次,我们都可以避免Stackoverflow。此外,我认为,如果由于任何给定的原因而导致连接失败,则立即调用Connect()方法是没有意义的。我认为在再次调用之前稍作休息将避免连续遇到类似的错误而不会中断。

您可以尝试以下方法:

async void Connect()
    {            
        Socket socket = null; //namespace System.Net.Sockets
        try
        {
            client = new TcpClient(ip, port);
            socket = client.Client; 
        }
        catch(SocketException se) //All socket related exceptions will be caught here
        {
            if (socket != null)
                socket.Close();
            //better to write exception in the log to fix the problem
            System.Threading.Thread.Sleep(1000 * 10); //Wait for few seconds before retrying
            Connect();
        }
        catch (Exception e)
        {
            HandleException(e); 
            //Connect(); // Try to connect again
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.