I am currently testing a C # managed network library that I wrote and I ran into a random issue. This problem manifests itself as a very sequential (always within 30 ms) 5000 ms block on networkstream.write (), possibly 1% of all sending operations. This is in a test environment, all of which run locally, using the same packet size (2 MB) each time. On the client side, I continuously write the following to the connected network stream:
tcpClientNetworkStream.Write(headerBytes, 0, headerBytes.Length); tcpClientNetworkStream.Write(dataBytes, 0, dataBytes.Length);
and on the server I use asynchronous read, waiting for data. After the data appears, I use the while loop through tcpClientNetworkStream.DataAvailable until all the data is received.
I know that networkstream.write () can block if the buffers are full, but if this is a problem, I cannot think of a faster way to clear them on the server (the default size of the send and receive buffer is 8192 bytes). The fact that the block is so consistent seems very strange. My first thought was probably some form of Thread.Sleep, but when performing a full search on the project, nothing is visible. If someone can help shed light on this issue, that would be greatly appreciated.
Mark
edit to add: The Hack, which seems to make the problem go away, looks like this (although there is a related performance improvement due to BlockCopy):
byte[] bytesToSend = new byte[headerBytes.Length + dataBytes.Length]; Buffer.BlockCopy(headerBytes, 0, bytesToSend, 0, headerBytes.Length); Buffer.BlockCopy(dataBytes, 0, bytesToSend, headerBytes.Length, dataBytes.Length); tcpClientNetworkStream.Write(bytesToSend, 0, bytesToSend.Length);
edit to add2: I also reproduced the problem using two asynchronous records with a stream signal between them. At the moment, the only solution I have is a single write operation, as in the edit above.
edit to add3: Okay, another possible fix follows. I'm still curious to know why sequential recording sometimes "blocks" in how this happens.
BufferedStream sendStream = new BufferedStream(tcpClientNetworkStream); sendStream.Write(bytesToSend, 0, bytesToSend.Length); sendStream.Write(packet.PacketData, 0, packet.PacketData.Length); sendStream.Flush();
edit to add4: after further extensive testing, the solution in 'edit to add3' does not fix the problem, it simply reduces the likelihood of occurrence to approximately 0.1% of shipments. Much better, but far from a solution. I will replace asynchronous reading with the following lock to see if this sorts, as suggested by PaulF.