none
請問我的 TcpClient 物件實體無法釋放... RRS feed

  • 問題

  •  

    請問一下... 小弟寫了個 Socket Server (TCP) 的程式...
    可是它卻無法把 TcpClient 的資源放掉...
    我用 Profiler 看 TcpClient 的實體從來沒有減少過... NetworkStream 也是...
    請幫忙看一下問題出在哪裡... 謝謝 ^^;;

     

    ---
    //這邊是宣告一個 TcpListener 並且收到一個連線就丟到 ThreadPool 裡面去工作
    TcpListener m_TcpServer = new TcpListener(System.Net.IPAddress.Any, m_Port);
    m_TcpServer.Start();

    while(true)
    {
      TcpClient AcceptClient = m_TcpServer.AcceptTcpClient();
      ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), AcceptClient);
    }

    // 這裡是 ThreadPool 所呼叫的 HandleRequest 方法
    private void HandleRequest(object Param)
    {
      using (TcpClient Client = (TcpClient)Param)
      {
        using (NetworkStream NetStr = Client.GetStream())
        {
          // 中略
          NetStr.Close();
        }
        Client.Close();

      }
    }
    ---
    我目前想到有可能的原因就是在 while 裡宣告的 AcceptClient 沒有被 Dispose
    但是它被丟進 ThreadPool 裡執行完應該要會自己 Dispose 啊...
    謝謝各位看完我的問題~~ 還請不吝賜教

    2008年1月29日 上午 06:12

所有回覆

  • Dear Sir

    根據MSDN上對於TcpClient.Close的說明

    http://msdn2.microsoft.com/zh-tw/library/system.net.sockets.tcpclient.close(VS.80).aspx

    Code Snippet

    Close 方法會將執行個體標記為已處置,但不會關閉 TCP 連接。呼叫這個方法不會釋放用於傳送和接收資料的 NetworkStream。您必須呼叫 Close 方法以關閉資料流和 TCP 連接。

     

     

    您可以在釋放參考之前明確呼叫TcpClient.Client.Close的方法看看。
    2008年1月29日 上午 06:52
  • 謝謝大大的指教, 我也有看到那篇文章...

    他給的程式碼範例差不多是這樣

    TcpClient tcpClient = new TcpClient();
    tcpClient.Connect("contosoServer", 11000);
    // Get the stream used to read the message sent by the server.
    NetworkStream networkStream = tcpClient.GetStream();
    // Set a 10 millisecond timeout for reading.
    networkStream.ReadTimeout = 10;
    // Read the server message into a byte buffer.
    byte[] bytes = new byte[1024];
    networkStream.Read(bytes, 0, 1024);
    //Convert the server's message into a string and display it.
    string data = Encoding.UTF8.GetString(bytes);
    Console.WriteLine("Server sent message: {0}", data);
    networkStream.Close();
    tcpClient.Close();

     

    我覺得我寫的也跟他一樣, 就是宣告一個 TcpClient, 然後Connect 到某電腦, port

    接著取得 NetworkStream, 做了一些事情後

    NetworkStream Close() TcpClient Close()

    但是這樣的結果就是我的 TcpClient 連同 NetworkStream 的物件實體都沒有被 release 掉

     

    還是說我不該使用 using(NetworkStream str = Client.GetStream){} ??

     

    謝謝大大賜教!
    2008年1月29日 上午 07:03
  • Hi,

    下面這篇可以參考看看

    NetworkStream.Close doesn't close the underlying Socket

     

    部分原文

    Code Snippet

    The documentation for the NetworkStream constructor (http://msdn2.microsoft.com/en-us/library/cd8fz0y3.aspx) says this...

     

    The NetworkStream is created with read/write access to the specified Socket. The NetworkStream does not own the underlying Socket, so calling the Close method does not close the Socket.

     

     

    2008年1月29日 下午 12:23
  • Hi,

    抱歉,我又仔細的看了一下,上一篇所提的情形跟您的情形應該不是相同的,要再找找資料;由其他文件中所提看起來應該是呼叫NetworkStream.Close就會釋放資料流與socket才對。

     

    2008年1月29日 下午 12:53