I am trying to write up a TcpClient implementation. I wanted to get the next read started while I was processing my data, but I am unsure of when the byte array I pass in to BeginRead is modified. Here is my current implementation
private void ProcessData()
{
byte[] buffer = new byte[_tcpClient.ReceiveBufferSize];
var networkStream = _tcpClient.GetStream();
IAsyncResult result = networkStream.BeginRead(buffer, 0, buffer.Length, null, null);
int read;
while ((read = networkStream.EndRead(result)) != 0)
{
result = networkStream.BeginRead(buffer, 0, buffer.Length, null, null);
ProcessChunk(buffer, read);
}
}
I started the next BeginRead before the long running function because I wanted the background IO to start getting the next chunk of data while I was processing. Can I do this with only one byte[] buffer, or do I need to alternate every BeginRead call?
private void ProcessData()
{
bool bufferChoice = false;
byte[] bufferA = new byte[_tcpClient.ReceiveBufferSize];
byte[] bufferB = new byte[_tcpClient.ReceiveBufferSize];
var networkStream = _tcpClient.GetStream();
IAsyncResult result = networkStream.BeginRead(bufferA, 0, bufferA.Length, null, null);
int read;
while ((read = networkStream.EndRead(result)) != 0)
{
if (bufferChoice)
{
result = networkStream.BeginRead(bufferA, 0, bufferA.Length, null, null);
ProcessChunk(bufferB, read); //Call function with B's buffer
}
else
{
result = networkStream.BeginRead(bufferB, 0, bufferB.Length, null, null);
ProcessChunk(bufferA, read); //Call function with A's buffer
}
bufferChoice = !bufferChoice;
}
}
There are generally no guarantees when buffer passed to BeginRead will be used. Theoretically it may be even synchronously filled during BeginRead call.
Side note: you should write code that is always behave correctly as it is so much easier to reason about than guess on particular behavior of particular implementation. In this case simply copy data or use multiple buffers so you never have outstanding IO and processing sharing the same buffer.