内存管理和异常处理

时间:2010-10-21 17:12:50

标签: c# memory-management exception-handling network-programming

我有一个简单的类来处理客户端和服务器之间的连接。

为了让多个用户同时与服务器通信,每个新的客户端连接都在一个单独的线程上进行。

在这个类中,我创建两个流作为客户端的入站和出站流。我首先创建字段,然后在单独的方法中初始化对象,因为该对象在其他几个地方使用。

我已经到了想要重构代码以使其更强大的地步,我的第一个调用端口是内存管理。我喜欢使用using()语句但是注意到由于代码的结构方式,我无法真正看到实现它的方法。 这意味着我有一个相当恼人的方法,仅用于关闭底层连接,仅此而已。

此外,我开始实现异常处理,并且好奇是将整个代码包装在带有try {}语句的方法中,然后使用带有适用异常类型的顺序catch()块的概念是最好的主意。 / p>

我希望我能正确解释自己,我会发一个片段给你看看。

谢谢!

//Fields
        TcpClient tcpClient;

        //The thread that will send information to the client
        private Thread thrSender;
        private StreamReader srReceiver;
        private StreamWriter swSender;
        private string currentUser;
        private string strResponse;

        //The constructor of the class takes in a TCP connection
        public Connection(TcpClient tcpCon)
        {
            tcpClient = tcpCon;

            //The thread that accepts the client and waits messages
            thrSender = new Thread(AcceptClient);

            //The thread calls the AcceptClient method
            thrSender.Start();
        }

        private void CloseConnection()
        {
            //Close the currently open objects
            tcpClient.Close();
            srReceiver.Close();
            swSender.Close();
        }

        //Occurs when a new client is accepted
        private void AcceptClient()
        {
            srReceiver = new StreamReader(tcpClient.GetStream());
            swSender = new StreamWriter(tcpClient.GetStream());

            //Read account information from the client
            currentUser = srReceiver.ReadLine();

            //Examine response from client
            if (currentUser != "")
            {
                //Store the user name in the hash table
                if (ChatServer.htUsers.Contains(currentUser) == true)
                {
                    //0 means not connected - Writes error to Client and Server log
                    swSender.WriteLine("0|This username already exists.");
                    swSender.Flush();
                    CloseConnection();
                    return;
                }
                //More if/else if/else statements
                //...  

        }

    }

1 个答案:

答案 0 :(得分:1)

你可以在AcceptClient方法中通过使它们成为局部变量来相当容易地处理这两个流,因为它们在其他地方没有被引用,如下所示:

private void AcceptClient()
{
    using (StreamReader srReceiver = new StreamReader(tcpClient.GetStream()))
    {
        using (StreamWriter swSender = new StreamWriter(tcpClient.GetStream()))
        {
            // ...
        }
    }
}

tcpClient更棘手,因为它是在一个线程上创建的,并在另一个线程上清理。除非你能改变它,否则最好的选择可能是在try / finally中实现清理。

private void AcceptClient()
{
    try
    {
        using (StreamReader srReceiver = new StreamReader(tcpClient.GetStream()))
        {
            using (StreamWriter swSender = new StreamWriter(tcpClient.GetStream()))
            {
                // ...
            }
        }
    }
    finally
    {
        tcpClient.Dispose();
    }
}

无论try子句是否抛出异常,都会调用finally子句。