.NET NetworkStream Lee lentitud
Tengo un código de red para procesar una conexión TCP arbitraria.
Todo parece funcionar como se espera pero parece lento. Cuando he perfilado el código, parece que ha pasado unos buenos 600 ms en NetworkStream.Read () y me pregunto cómo mejorarlo. He jugado con los tamaños de búfer y he alternado entre un búfer masivo para leer todos los datos de una sola vez o uno pequeño que debería concatenar los datos en un StringBuilder. Actualmente, el cliente que estoy usando es un navegador web, pero este código es genérico y puede que no sea un dato HTTP que se le envíe. ¿Algunas ideas?
Mi código es este:
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();
}
}
}
Edición: obtengo aproximadamente las mismas cifras en dos máquinas completamente separadas (mi máquina de desarrollo XP y una caja 2003 en un colo). He puesto un poco de tiempo en el código alrededor de las partes relevantes (usando System.Diagnostic.StopWatch) y lo vuelco en un registro:
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