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

非常好,謝謝! – 2010-10-23 19:17:33

+0

不客氣! – Steve 2010-10-24 09:33:23