1

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

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

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

Я пришел к тому моменту, когда хочу реорганизовать код, чтобы сделать его более надежным, моим первым портом вызова было управление памятью. Я полюбил инструкцию 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

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

+0

Отлично, спасибо! –

+0

Добро пожаловать! – Steve

Смежные вопросы