Управление памятью и обработка исключений - PullRequest
1 голос
/ 21 октября 2010

У меня есть простой класс, который обрабатывает соединение между клиентом и сервером.

Чтобы позволить нескольким пользователям одновременно взаимодействовать с сервером, каждое новое клиентское соединение устанавливается в отдельном потоке.

В этом классе я создаю два потока, которые действуют как входящие и исходящие потоки для клиента. Сначала я создаю поля, а затем инициализирую объект отдельным методом, просто потому, что этот объект используется в нескольких других местах.

Я пришел к моменту, когда я хочу реорганизовать код, чтобы сделать его более надежным, моим первым портом вызова было управление памятью. Я полюбил оператор using (), но заметил, что не могу найти способ реализовать его из-за структуры кода. Это означает, что у меня есть довольно раздражающий метод, который просто используется для закрытия базовых соединений и ничего более.

Кроме того, я пришел к реализации обработки исключений и мне было любопытно, была ли идея обернуть весь код в метод с помощью оператора try {}, а затем иметь последовательные блоки catch () с применимыми типами исключений.

Надеюсь, я все правильно объяснил, я выложу фрагмент, чтобы вы могли на него посмотреть.

Спасибо!

//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 Ответ

1 голос
/ 21 октября 2010

Вы можете довольно легко избавиться от двух потоков в методе 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();
    }
}

Предложение finally будет вызвано независимо от того, выдает ли предложение try исключение.

...