1

J'ai une classe simple qui gère la connexion entre un client et un serveur.Gestion de la mémoire et gestion des exceptions

Pour permettre à plusieurs utilisateurs de communiquer simultanément avec le serveur, chaque nouvelle connexion client est effectuée sur un thread distinct.

Dans cette classe, je crée deux flux qui agissent en tant que flux entrants et sortants pour le client. Je crée d'abord les champs, puis j'initialise l'objet dans une méthode séparée, simplement parce que l'objet est utilisé à plusieurs autres endroits. Je suis arrivé au point où je veux refactoriser le code pour le rendre plus robuste, mon premier port d'escale était la gestion de la mémoire. J'en suis venu à aimer la déclaration using(), mais j'ai remarqué que je ne vois pas vraiment comment l'implémenter en raison de la structure du code. Cela signifie que j'ai une méthode plutôt ennuyeuse qui est juste utilisée pour fermer les connexions sous-jacentes et rien de plus. En outre, je suis arrivé à implémenter la gestion des exceptions et j'étais curieux de savoir si l'idée d'encapsuler tout le code dans une méthode avec une instruction try {} et d'avoir des blocs catch() séquentiels avec les types d'exceptions applicables était la meilleure idée.

J'espère que je me suis expliqué correctement, je vais poster un extrait pour vous de regarder.

Merci!

//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 
       //... 

     } 

    } 

Répondre

1

Vous pouvez disposer des deux courants assez facilement dans la méthode de acceptClient en les variables locales car ils ne sont pas référencés ailleurs quelque chose comme ceci:

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

Le tcpclient est plus délicate car elle est créé sur un fil et nettoyé sur un autre. À moins que vous ne puissiez changer cela, la meilleure option sera peut-être d'implémenter le nettoyage dans un essai/finalement. La clause finally sera appelée si la clause try renvoie ou non une exception.

+0

Excellent, merci! –

+0

De rien! – Steve