views:

79

answers:

1

The following piece of code runs fine when parallelized to 4-5 threads, but starts to fail as the number of threads increase somewhere beyond 10 concurrent threads

int totalRecieved = 0;
int recieved;
StringBuilder contentSB = new StringBuilder(4000);
while ((recieved = socket.Receive(buffer, SocketFlags.None)) > 0)
{
   contentSB.Append(Encoding.ASCII.GetString(buffer, 0, recieved));
   totalRecieved += recieved;
}

The Recieve method returns with zero bytes read, and if I continue calling the recieve method then I eventually get the exception 'An established connection was aborted by the software in your host machine'. So I'm assuming that the host actually sent data and then closed the connection, but for some reason I never received it.

I'm curious as to why this problem arises when there are a lot of threads. I'm thinking it must have something to do with the fact that each thread doesn't get as much execution time and therefore there are some idle time for the threads which causes this error. Just can't figure out why idle time would cause the socket not to receive any data.

Edit: Just to clarify. Each thread has its own personal socket reading different data.

+1  A: 

The issue is attempting to use Receive on the same socket on multiple threads.

MSDN documentation for the Socket class specifically recommends that a socket's Receive method be used only by a single thread one thread during execution.

For an application that requires multiple threads to read data from the same socket, you should either:

  • Use BeginReceive and EndReceive, as recommended by MSDN, or

  • Use a single socket read thread to receive packets, then write each packed to a synchronized queue. You may then have multiple threads pull data off of the queue.

Justin Ethier
Good point. Guess I'll change to an async approach. Still doesn't understand why a sync approach would fail.
Qua
MSDN specifically states that you should not use `Receive` processing communications with more than one thread. Since execution of threads is non-deterministic, their implementation probably just happened to (or appeared to) work correctly with fewer than 4 threads.
Justin Ethier
The MSDN wording is a little confusing, it's not a problem to use `Receive` when you have multiple threads. The issue is attempting to use `Receive` on the same socket on multiple threads. There's no problem using this on two different threads if each thread is handling a different socket.
Kevin Brock
The MSDN example also has bugs - for one they don't close the socket in the method that opens the socket and returns a string.
Kevin Brock
@Kevin - Thanks, that's what I was trying to say, but I did not really get the point across. The answer has been updated to make it more clear.
Justin Ethier