.NET NetworkStream Powolność odczytu

Mam kod sieciowy do przetwarzania dowolnego połączenia TCP.

Wszystko wydaje się działać zgodnie z oczekiwaniami, ale wydaje się powolne. Kiedy wyprofilowałem kod, wydaje się, że spędza dobre 600 ms w NetworkStream.Read () i zastanawiam się, jak go ulepszyć. Bawiłem się rozmiarami buforów i przełączałem między ogromnym buforem, aby odczytać wszystkie dane za jednym razem lub małym, który powinien połączyć dane w StringBuilder. Obecnie klient, którego używam, jest przeglądarką internetową, ale ten kod jest ogólny i może nie być przesyłanymi do niego danymi HTTP. Jakieś pomysły?

Mój kod jest następujący:

    public void StartListening()
    {
        try
        {
            lock (oSyncRoot)
            {
                oTCPListener = new TcpListener(oIPaddress, nPort);

                // fire up the server
                oTCPListener.Start();

                // set listening bit
                bIsListening = true;
            }

            // Enter the listening loop.
            do
            {
                // Wait for connection
                TcpClient newClient = oTCPListener.AcceptTcpClient();

                // queue a request to take care of the client
                oThreadPool.QueueUserWorkItem(new WaitCallback(ProcessConnection), newClient);
            }
            while (bIsListening);
        }
        catch (SocketException se)
        {
            Logger.Write(new TCPLogEntry("SocketException: " + se.ToString()));
        }
        finally
        {
            // shut it down
            StopListening();
        }
    }

    private void ProcessConnection(object oClient)
    {

        TcpClient oTCPClient = (TcpClient)oClient;
        try
        {
            byte[] abBuffer = new byte[1024];
            StringBuilder sbReceivedData = new StringBuilder();

            using (NetworkStream oNetworkStream = oTCPClient.GetStream())
            {
                // set initial read timeout to nInitialTimeoutMS to allow for connection
                oNetworkStream.ReadTimeout = nInitialTimeoutMS;

                int nBytesRead = 0;

                do
                {
                    try
                    {
                        bool bDataAvailable = oNetworkStream.DataAvailable;

                        while (!bDataAvailable)
                        {
                           Thread.Sleep(5);
                           bDataAvailable = oNetworkStream.DataAvailable;
                        }

                        nBytesRead = oNetworkStream.Read(abBuffer, 0, abBuffer.Length);

                        if (nBytesRead > 0)
                        {
                            // Translate data bytes to an ASCII string and append
                            sbReceivedData.Append(Encoding.UTF8.GetString(abBuffer, 0, nBytesRead));
                            // decrease read timeout to nReadTimeoutMS second now that data is coming in
                            oNetworkStream.ReadTimeout = nReadTimeoutMS;

                        }
                    }
                    catch (IOException)
                    {
                        // read timed out, all data has been retrieved
                        nBytesRead = 0;
                    }
                }
                while (nBytesRead > 0);

                //send the data to the callback and get the response back
                byte[] abResponse = oClientHandlerDelegate(sbReceivedData.ToString(), oTCPClient);
                if (abResponse != null)
                {
                    oNetworkStream.Write(abResponse, 0, abResponse.Length);
                    oNetworkStream.Flush();
                }
            }
        }
        catch (Exception e)
        {
            Logger.Write(new TCPLogEntry("Caught Exception " + e.StackTrace));
        }
        finally
        {
            // stop talking to client
            if (oTCPClient != null)
            {
                oTCPClient.Close();
            }
        }
    }

Edytuj: Dostaję mniej więcej te same dane na dwóch całkowicie oddzielnych maszynach (mój komputer XP i 2003 w colo). Umieściłem trochę czasu w kodzie wokół odpowiednich części (używając System.Diagnostic.StopWatch) i zrzuciłem go do dziennika:

7/6/2009 3:44:50 PM : Debug : While DataAvailable took 0 ms
7/6/2009 3:44:50 PM : Debug : Read took 531 ms
7/6/2009 3:44:50 PM : Debug : ProcessConnection took 577 ms

questionAnswers(3)

yourAnswerToTheQuestion